Vibrant discussion about CSLA .NET and using the framework to build great business applications.
I would like to solve the following problem. As stated in subject, I want to define business rules with the ability to take in mind the context or condition by which they behave once as error and once as warning.
The context/condition may represent business state or business operation which I would like to set or execute.
But the problem is that I would like to proactively check the rules before the operation or the state would change so that I could display the reason why he cannot do some business operation.
What would you propose to do? How would you solve such thing?
I have some ideas but I'm not satisfied with them.
1. Use undo mechanism
- Take the snapshot of the root object.
- Change the object to desired state or execute business operation which could involve changing the state of object at different levels (child objects).
- Execute the rules and check if the object is valid or not
- if not, display the reason to the user from the BrokenRules collection
- undo the state of object
2. Use rule sets
- Create the rule set for each business operation you need to be able preventively check if it will break the rules or not.
- set the current ruleset for current business operation you want to check if there are business rules met for executing the business operationn
- set the current ruleset to 'default'
The first option is too robust and gives some performance penalty and when bound to Windows Forms controls, unbound operation is needed to be performed before taking snapshot, which is slow UI operation.
So I would rather go with the 2nd option, but this gives me some questions to ask.
1. Does setting the RuleSet on root object, "sets" the RuleSet also for all child objects in object graph?
If not, how to deal with it?
2. Is this the right approach to conditionaly evaluate business rules on the state which hasn't been set yet?
Or do you have any other idea to achieve this?
If you're looking to see if the object would have errors if it is in the other state, you could clone the object and then mark it as in the other state. After that you just check the rules on the clone, but it probably won't be that performant either.
The final solution I've used, was to create pair methods Can<DoSomething> and <DoSomething> method with registering it with RegisterMethod in Csla.
Then in Can<DoSomething> I use Clone method on and modify the cloned object to desired state. After that I can use business rules (as they were designed for business object without knowing anything about operation that I'm trying to perform) to see if something went wrong or not a display the information to the user.
This is working just fine.
If you want to check this before the value/state is actually changed then you should probably not use the rule engine for this.
On the other hand you could call
My preference is to NOT use RuleSets but you could accomplish this by creating separate RuleSets. Just be aware that each rulesetmust be a "complete" ruleset.
So to your questions:
Jonny Bekkum, Norway
Maybe use a Gate rule. See here for an example http://forums.lhotka.net/forums/p/9427/44686.aspx
The gate rule could look for the exiting error, and change the error type if it matches.
thank you for your opinion. I was hoping that there exists something much simpler or more elegant solution than that sequence.
That sequence is very similar to my proposed idea except yours has combined the rulesets which I was trying to use separately.
But even though this method when using Windows Forms, isn't very suitable, because you have to unbind the object from UI, perform that sequence and finaly bind UI back. Unfortunately this leads to unwanted flickering and quite a big overhead in performance and delay which I'm trying to avoid.
Don't you have better idea? There must be something in Csla core that I could use. Or you might be plan some feature that would allow to do this.
I'm currently using the gateway rules to achieve warning results when the object is in the state A and error results when the object is in the state B.
But this doesn't help me to ask whether the object in the state A will be in error if I switch it to state B.
Probably there aren't any other good options to choose from than those I've proposed and JonnyBee confirmed them to me.
Thanks for your time.