Hi all,
I have experienced some challenges with the rule engine and have been working on improvements for Csla 4.2 that I'd like to geed feedback on.
Please - read on and consider where you have had shortcomings/challenges with the rule engine and if these changes will allow you to create rules as you need them!!
Feedback is really appreciated.
The primary goal and guidelines:
Existing problem areas:
Implicit dependencies?
(So far) whenever I have InputProperties to a rule I find that I need to add a Dependency rule for each InputProperty to make the rule run whenever one of the input properties is changed.
So should the rule engine after completing rules for this PrimaryProperty then rerun rules for both affected properties AND properties where this PrimaryProperty is an InputProperty (that is - implicit Dependency based on InputProperties)?
Changes for Csla 4.2 that will now enable us to:
This also enables us to create new rule base classes like:
- BusinessRule - existing base class with no restrictions on when rule runs.
- ObjectRule - will always have PrimaryProperty == null.
- PropertyRule - basic PropertyRule with no restrictions on when rule runs
- PropertyInputRule - validate user input on client side of DataPortal, ie run on PropertyChanged and as
AffectedProperty from another rule and CheckRules but NOT on DataPortal
serverside (DAL code).
- LookupRule - lookup data on client side when user edited a field, NOT
run as AffectedProperty, CheckRules or on DataPortal
serverside (DAL code).
The restrictions is (at the base class level) implemented as boolean properties (suggested names):
CanRunOnServer
CanRunInCheckRules
CanRunAsAffectedProperty
I'm sure there are other problems/challenges that you have experienced?
Will these changes help you create better and simpler rules?
Sorry, I don't have any suggestions, but it looks like you've spelled out all the issues I've had and I think your solutions are reasonable.
Thanks
Can you please expand a little more on how LookupRule would work. From the post above, the PropertyInputRule sounds like a "Command Object" that hits a local store for "constraint" validation.
Hi Blake,
Good question.
Lookup rule is configured to run as async (by default) to perform lookups only when a property has been changed/edited by the user and most probably only in a rich-client UI. And LookupRules should not do validation.
PropertyInputRule would be preferred for validation and sync rules in a Web/RichClient environment.
My own personal guidance:
All rules that perform validation should run on CheckRules and (CheckObjectRules or CheckRulesForProperty).
LookupRules would typically only run on PropertyHasChanged and NOT CheckRules
I have just come across an issue with the new feature:
Implicit dependencies?
(So far) whenever I have InputProperties to a rule I find that I need to add a Dependency rule for each InputProperty to make the rule run whenever one of the input properties is changed.
So should the rule engine after completing rules for this PrimaryProperty then rerun rules for both affected properties AND properties where this PrimaryProperty is an InputProperty (that is - implicit Dependency based on InputProperties)?
When I execute BusinessRules.CheckRules() the same rule gets executed multiple times, once for the PrimaryPrimary and then once for each InputProperty. This is an issue since my rules can be async. My perference is the old behaviour. If I want the rule to execute I will add the the property to the AffectedProperties. Is there any way of turning off the InputProperties dependencies?
Hi,
True, a rule can be executed many times during CheckRules.
For async rules I typically inherit from CommonRules.CommonBusinessRule and sets all the CanZYZ flags to false:
CanRunOnServer
CanRunInCheckRules
CanRunAsAffectedProperty
The end result is that the rule is only executed when the PrimaryProperty is changed on the "Client" side and typically by the end user. If you allow any asyn rule to execute as AffectedProperty (or Dependency) from other fields then it will run multiple times even when there is only AffectedProperties as dependencies (the "old" style).
There is no way of turning off the InputProperties as dependencies other than not adding InputProperties.
You should be aware that the rule engine will merge all AffectedProperties and InputProperties - select distinct where Property != PrimaryProperty and rerun the rules. It will not run multiple time as the result of that single property.
I am considering this one change tho':
http://www.lhotka.net/cslabugs/edit_bug.aspx?id=1007
as this would stop CheckRules from running the rule unnecessarily many times, whether the rule is sync or async.
I run the CheckRules in DataPortal_Create and DataPortal_Fetch because I do not trust the data in the database. Is there another way of passing a value to the rule without using InputProperties or by setting it in the rule constructor?
The change to stop CheckRules from running rules unnecessarily is good. It is a start but you also need to stop any dependencies from running the rules. e.g. A Start date before End date rule currently executes 4 times. It only needs to execute 2 times, once for StartDate and once for EndDate.
The change to stop CheckRules from running rules unnecessarily is good. It is a start but you also need to stop any dependencies from running the rules. e.g. A Start date before End date rule currently executes 4 times. It only needs to execute 2 times, once for StartDate and once for EndDate.
That is a whole other aspect and we are not planning on changing that.
When the rule engine checks the rules for StartDate and that rule has EndDate as AffectedProperty (or a separate DependencyRule) the RuleEngine runs that rule as if the StartDate propert was changed in CheckRules. The Rule engine will have no knowlegde of whether the rule also changed EndDate (ie - the rule updated another field) or not and so the effect is:
StartDate - check rule for EndDate too.
EndDate - check rule for StartDate too.
Assuming that you have the same rule for both properties then yes - that rule is executed 4 times.
Having InputProperties as dependency means that you do not have to add dependency rules or set the other property as affected property of first property.
Also remember - rules can update field by calling LoadProperty or AddOutValue. The latter one may be tested for - the first is unknown to the rule engine.
Copyright (c) Marimer LLC