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