CSLA 4.5 RuleEngine update

The rule engine for CSLA 4.5.10 has been updated with a new advanced mode.

By default BusinessRules is run as follows when a property is edited by a user:

  1. Call CheckRulesForPropertymethod with parameters Property and Cascade=true
    1. Clear all BrukenRules from the Property
    1. Get list of BusinessRules for Property
    2. Call RunRuleswith parameters RulesForProperty and Cascade=true to run rules for this property.
      1. ForEach rule in RulesForProperty
        1. Call Rule.Execute method
      2. Update property values from context.OuputProperties collection
        1. if value was changed add Property to DirtyProperties
      3. Return RuleResult –  a list of AffectedProperties and lst of DirtyProperties
    3. If  (cascade)
      1. For the aggreate of (context.AffectedProperties from the rules checked) and
        (properties that have BusinessRules with PrimaryProperty as InputProperty)
        take distinct PropertyInfo

        1. call CheckRulesForProperty with parameters Property and Cascade=false.

But then the rule engine stops is rechecking. So the rule engine will only cascade down to the next level and then stop rechecking rules.
The consequence of having properties changed by f.ex. OutputProperties in the second run when Cacade=false is that the Property and RuleResults may get out of sync and a field that has a valid value may be invalid and vice versa.

So this may be a serious problem unless you have taken care of this in designing you business rules. In some financial applications you may also have a lot of calculations that should cascade for all “dirty” properties to rerun rule for as long as properties is changed – much like Excel does in a spreadsheet for calculating formulas  and cascade calculation for as long as cells is updated.

So to provide this level of functionality the RuleEngine for CSLA 4.5.10 has been updated with a new configuration flag:
<bo>.BusinessRules.CascadeOnDirtyProperties.
This is an instance level flag that must be set in the Create/Fetch method of the <bo>.

When CascadeOnDirtyProperties is true the rule engine run rules as follows:

  1. Call CheckRulesForPropertymethod with parameters Property and Cascade=true
    1. Clear all BrukenRules from the Property
    1. Get list of BusinessRules for Property
    2. Call RunRuleswith parameters RulesForProperty and Cascade=true to run rules for this property.
      1. ForEach rule in RulesForProperty
        1. Call Rule.Execute method
      2. Update property values from context.OuputProperties collection
        1. if value was changed add Property to DirtyProperties
      3. Return RuleResult –  a list of AffectedProperties and lst of DirtyProperties
    3. If (cascade)
      1. For the aggreate of (context.AffectedProperties from the rules checked) and
        (properties that have BusinessRules with PrimaryProperty as InputProperty)
        take distinct PropertyInfo

        1. call CheckRulesForProperty with parameters Property and Cascade=true if property is in DirtyProperties list .

Of course – unless your BusinessRules is carefully crafted you may end up with an infinite loop and eventually a StackOverflow exception.
But if you really need to make sure that BusinessRules is actually rerun for as long as property values is updated from context.OutputPropertyValues then this will be a nice extension to the rule engine.

The above sequence diagrams is simplified when it comes to asynchronous rules but the end result is the same behavior for both synchronous and asynchronous rules.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s