Business rules for interdependent properties

Business rules for interdependent properties

Old forum URL: forums.lhotka.net/forums/t/11449.aspx


kgulden posted on Tuesday, July 03, 2012

I am using CSLA 4.3.12.0 and am struggling with understanding how to structure a particular business rule.  I am out in the wilderness wandering...  I have great hope someone on this forum can help.

I have two PropertyInfo's A and B in a root object.  PropertyInfo-A is a string, PropertyInfo-B is a datetime.  The business rule requires both values before it invokes an expensive asynchronous operation ( named ExpensiveRule).  Both properties have other rules like min/max values.  However, when ExpensiveRule is invoked by the framework, only the primary-property (PropertyInfo-A) associated with ExpensiveRule has had its lower priority rules applied and enforced, the dependency property (PropertyInfo-B) contains raw data without any rules applied.  The basic rule syntax is:

... priority=0 rules for PropertyInfo-A and PropertyInfo-B go here...

BusinessRules.AddRule(new ExpensiveRule(PropertyInfo-A, PropertyInfo-B){Priority=1,RunMode=Csla.Rules.RunModes.DenyOnServerSidePortal});

The trouble is, the ExpensiveRule is feed this raw, unvalidated data and must re-apply all the same rules before it can run properly.  Is there any way to have a dependency property (PropertyInfo-B) have its rules run and/or enforced beforehand so that ExpensiveRule needs not perform double-duty?

(Thanks ahead of time for anyone how even read this and understood it.)

JonnyBee replied on Wednesday, July 04, 2012

Hi,

The rule engine itself does not provide support for this.

You can achive this by making the ExpensiveRule an object rule (with PrimaryProperty = null) and override the PropertyHasChanged method.

    protected override void PropertyHasChanged(IPropertyInfo property)
    {

      var AandB = new List<IPropertyInfo> {AProperty, BProperty};

      // Run rules for Property and Dependent properties.
      base.PropertyHasChanged(property);
     
      // was A or B changed
      if (AandB.Contains(property))
      {
        // check if there are broken rules on A or B then return
        if (BrokenRulesCollection.Any(p => AandB.Any(o => o.Name == p.Property) && p.Severity == RuleSeverity.Error))
          return;

        // call check object rules to start expensive rule.
        BusinessRules.CheckObjectRules();
      }
    }

 

kgulden replied on Wednesday, July 04, 2012

Thanks Jonny.  I truly appreciate the quality of your response.  I faguely guessed I was "swimming up stream".  I need this functionality, so I will incorporate your prescribed solution.

Copyright (c) Marimer LLC