Selective Addition of Business Rules

Selective Addition of Business Rules

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


MadGerbil posted on Tuesday, March 30, 2010

I've an object that comes in two varieties.

Both varieties use about 50 business rules and they share about 40 of them. I'd like to be able to load up the business rules selectively, based upon a property value, however the business rules are added before any object properties are loaded, that is, during hte intialization of the base class.

Is there a way to load the object first (property values), then add the rules, and then check them?

AaronH replied on Tuesday, March 30, 2010

Just off the top of my head, you could create a base class (inheriting from BusinessBase<T>) and create 2 subclasses, each one overriding AddBusinessRules(). 

Don't forget to call base.AddBusinessRules()!

RockfordLhotka replied on Tuesday, March 30, 2010

The idea behind the rules system is that you'd load the 50 rules, and the rules would be smart enough to adapt to the state of the object.

In other words, rather than making the process of adding rules smarter, make the rules themselves smarter.

MadGerbil replied on Tuesday, March 30, 2010

Yeah, I was afraid I'd have to do that, but it does seem to be the very best answer.

rsbaker0 replied on Tuesday, March 30, 2010

I agree with Rocky on this for the most part, except that I really did find what I think is a use case for the per instance rules that the per type rules don't handle well at all.

I also found the per-instance rules were added by the base class constructuctor. which as you noted means you can't use property values to decide what rules to add.  It turns out, however, that you can add your own instance rules "later" and it works well for the most part. 

There are some gotchas, though. If you are using a remote data portal, the rules don't get serialized across with the object. Instead, it calls InitializeBusinessRules() again in OnDeserializedHandler(), so you have to plan for this if it matters in your particular case.

RockfordLhotka replied on Tuesday, March 30, 2010

For better or worse however, per-instance rules will not be in CSLA 4. On the upside, the new flexibility in the rules system should allow for "gate rules" - a rule that evaluates whether to allow some other rule to run, thus acting as a gate. It is one application of the broader concept of rule chaining, where one rule can invoke other rules, consolidating the results and returning them to the framework when complete.

rsbaker0 replied on Tuesday, March 30, 2010

^^^^

I think I could safely refactor my current implementation to use a different derived class for the special cases where I need instance rules. I actually know what rules are needed at the time the object is constructed, so this would be a straightforward (if only slightly tedious) transformation.

MadGerbil replied on Tuesday, March 30, 2010

I tried creating a AddBusinessRulesAfterLoad() method which gets called after the business object is loaded. Inside of that I call base.AddBusinessRules() but for some reason only the first object in the collection gets it's rules loaded.

JoeFallon1 replied on Tuesday, March 30, 2010

I have an object that comes in three varieties and share numerous rules. A few years ago I did something like this:

1. Place as many common rules as possible in the base class.

2. Inherit the final type for the 1stBO from the base class and then use code like this:

Protected Overrides Sub AddBusinessRules()
  MyBase.AddBusinessRules()

 
If TypeOf Me Is 2ndBO OrElse TypeOf Me Is 3rdBO Then
   
'Do not add 1stBO Type rules
 
Else
   
'Add more rules here that are just for 1stBO type
  End If

End Sub

3. Inherit the 2nd and 3rd BO types from the 1stBO type. Then they can have code like this:

Protected

Overrides Sub AddBusinessRules()
 
MyBase.AddBusinessRules()

  'Add more rules here that are just for 2nd or 3rd BO types.

End Sub


Notice that by inheriting from the 1st BO type the 2nd and 3rd types get the common rules only. They do not get the rules that are specific to the 1st BO type due to the line that reads:   If TypeOf Me Is 2ndBO OrElse TypeOf Me Is 3rdBO Then


This trick worked correctly because it relied on the type of the BO (not the value of a Property which has not been loaded yet.) So these are still per type rules, not Instance rules.

Joe

Copyright (c) Marimer LLC