Is there a way to stop the BusinessRule execution if certain value is set on the Object?
I know that I can Short-Circuit the process using the Rules Priorities and ProcessThroughPriority; but it is my understanding this will only happen if the rule has failed. What I need is for the rule to still be valid but if certain value are set the rules with lower priority (higher number) shouldn't run.
In my example, an order entry, I calculate all prices, discount, taxes etc for a normal order, but if the user marks it as been a 'Free Order' I don't want to go through all those unneeded calculations.
Yes, your rule can call AddSuccessResult(true) to not fail, but to prevent subsequent rules from running.
Combine that feature with rule priorities, and you can have a rule that blocks other rules from running.
For example, create this "preventer" rule and add it at priority -1 so it runs before any normal rules at priority 0.
You answer does exactly what you said it would, but I realized that my question is not what I really need. After tinkering around with this I think I'm not understanding how the rules work because after applying all the 'Pricing" and "Discount" rules, I'm ending up with a 'Stack Overflow" error.
I try using the context.AddOutValue or even the LoadProperty to prevent recursive Rule execution, which works, but then the UI doesn't get refreshed with the new values. So I'm setting the values casting the context.target and using object.property = value but then all the other rules start running and since I'm setting new values for each of the children on a collection that's where I belive the 'Stack Overflow" is happening.
Any way, back to drawing board I guess.
P.S.: Jonny the clacontrib has some wonderful rules I can use, the only issue is finding the code, I wasted some time trying to find then from the 'Recommended" download, then I figured I had to use the 'Source Code". But then I feel I might be using unstable code.
To use AddOutValue you should have to add those properties to the AffectedProperties list. When the first rule completes, that should cause the rules to be run for the affected properties as well. At the very end, the PropertyChanged event should be automatically raised for each affected property (CSLA maintains a list of all the affected properties and raises those events).
There are cases where PropertyChanged events are not automatically raised, because the code is assumed to be running in a non-interactive environment:
But in a normal interactive scenario, where a property is changed through its setter, that will cause PropertyHasChanged to be invoked. PropertyHasChanged will have the BusinessRules object run all the rules for the property and affected properties, and then it raises PropertyChanged events for each affected property.
I have one rule that resets the value of a property to it's previous value using context.AddOutValue() it is in the AffectedProperties list. But the other rules I have for that poperty are not run again after AddOutValue is called.
I put a breakpoint in the following CSLA function and PropertyHasChanged is not called because markDirty = false
LoadPropertyValue<P>(PropertyInfo<P> propertyInfo, P oldValue, P newValue, bool markDirty) Should I call PropertyHasChanged from my rule that resets the value?
LoadPropertyValue<P>(PropertyInfo<P> propertyInfo, P oldValue, P newValue,
Should I call PropertyHasChanged from my rule that resets the value?
That would really create a recursive check rules!!!
Problem is that when the Rule engine updates the value it doesn't really know if the value was changed or not and so will not "retrigger" rules on the original property.
It might be possible to use:
You could also look at the additional rules in CslaContrib and specifically the StopIfNotCanWrite rule.
Copyright (c) Marimer LLC