AddInstanceRule Query

AddInstanceRule Query

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


rory posted on Thursday, May 28, 2009

Hi,

I wish to use the AddInstanceRule() to implement "usage" dependant logic for business rules.

These InstanceRules however, are added after an instance of the object has been created and values on the object have been set.

Ideally, the solution would be to have to separate implementations of the same object depending on the usage, but this cannot be determined until the user decides to save the object. This is presented via the U.I. as an option to either "Save" or "Submit" the business object.

Depending on the option selected different instance rules are to be applied.

I have implemented this functionality by calling a custom method on the business object which deals with a "save" or a "submit" which in turn calls AddSaveRules() or AddSubmitRules() each of which adds a different set of rules using AddInstanceRule() and finally calls ValidationRules.CheckRules() for the object.

The problem i am having is that the call to CheckRules does not seem to include the newly added InstanceRules.

Having had a look at CheckRules, it references the property RulesToCheck, which compiles a list of rules based on

if (_rulesToCheck == null)
{
          ValidationRulesManager instanceRules = GetInstanceRules(false);
          ValidationRulesManager typeRules = GetTypeRules(false);
          if (instanceRules == null)
          {
            if (typeRules == null)
              _rulesToCheck = null;
            else
              _rulesToCheck = typeRules;
          }
          ....
}

return _rulesToCheck;

when the business object is initialised to start with (via a get)

GetInstanceRules() returns null

however

GetTypeRules() returns a default ValidationRulesManager with a RulesDictionary with 0 elements.

It appears then, that when I at a later point call CheckRules, as _rulesToCheck is not null, it does not get past

if (_rulesToCheck == null)

to "re-evaluate" the instanceRules.

Is it the case that i am using the AddInstanceRule method in an incorrect fashion?

As i said, i do realise that a better implementation would be to use different business objects for each use case.

An alternative solution for me is to use AddRule, and a partial non-persisted tri-state property on the object that can be evaluated in the rules as "Unset, Save, Submit" which is set when the user decides to either save or submit the business object.

JoeFallon1 replied on Thursday, May 28, 2009

I avoid instance rules completely. I think they are the original implementation and Rocky quickly added type rules to the framework to reduce the overhead. They should be treated as legacy code in my opinion.

Just add a type rule to the BO and use the strongly typed delegate to enable your BO to see all of its fields and properties. Then just write branching code inside that method to determine if traget.Submit was clicked or target.Save was clicked.

Joe

Fintanv replied on Thursday, May 28, 2009

Joe,

For the most part I agree with your take on instance rules (less performant, more memory etc.).  However I do not agree that they are 'legacy'.  There are certain situations where they are useful, and dare I say it, 'required'.  I have a system where the user can specify the number and datatype of samples they wish to collect.  They can attach rules to the sample input which are stored in the database.  On the data entry screen these are read and applied as instance rules (since they do vary from object to object and not just class to class).  Instance rules should definitely be used judiciously, but they are useful at times.

Regards,

Fintan

triplea replied on Thursday, May 28, 2009

Not really sure what happens to your instance rules when you Clone() your object during save. Maybe you are doing the following:

1. Add instance rules
2. Save object (auto or manual clone should occur)
3. At that stage you loose your rules.

Setting the fact that you might want to reconsider your design aside, what if you implement your own rules like the start/end date rule in project tracker (StartDateGTEndDate<T>). Then you can just stick all your rules as type rules and still be flexible with the logic...

rory replied on Friday, June 05, 2009

rory:
Hi,
An alternative solution for me is to use AddRule, and a partial non-persisted tri-state property on the object that can be evaluated in the rules as "Unset, Save, Submit" which is set when the user decides to either save or submit the business object.


This is the solution I have run with.

I was still wondering however, about the behaviour of "GetTypeRules" returning a non-Null empty RulesDictionary which "short-circuits" the _rulesToCheck == null if statement in CheckRules

Copyright (c) Marimer LLC