I ll start this post with a phrase : WE HAVE TO REMEMBER TO NOT REINVENT THE WHEEL .
Why I say that?
XAF with the help of eXpand is now a very mature framework. Almost all the tools required for build LOB applications are here. XAF has many ruling engines (Validation,EditorState,Appearence) and eXpand also the same (AdditionalViewControls, ModelArtifactState, MasterDetail, ConditionalDetailViews).
All the above engines provide a way to describe behaviors using rules and they operate over certain Contexts. What is a context some of you may ask. The answer is simple, context means the “when” the rule is going to be evaluated. For example Validation rules have 2 predefined contexts , those are Save,Delete.
I am going to give an example of how powerful a context is . Let say we have a Customer-Order relationship and we have 2 cases like the following
- First record of Customer Orders cannot be deleted.
- Only the last record of Customer Orders can be deleted
So what we need to design the above rules? First of all since both cases speak about the index of Order record we need to adjust our Order class to provide that info. If you use eXpand the code should be similar to
And the second step is to decorate the Orders collection of the Customer class with 2 RuleValueComparison attributes
As you see we have 2 rules that operate on the Delete context and check the value of the Sequence property against an Aggregation. That is a very powerful approach cause we used the Validation engine that is fully tested and we just describe our scenario declaratively using attributes. In fact we could do the same at runtime using the Model editor.
But let me add 2 more cases
- Only the last record of Customer Orders can be cloned
- Only the last record of Customer Orders can be edited
From a first look seems that validation engine cannot help us here, but if we think again we will notice that only the deleted word changed to cloned/edited. In other words only the context change so we could just add the “Cloned;Edited” context to our last rule
and write some code that will force the Validation engine to execute for our custom contexts as well.
The only caveat here is that you have to manually write the above code for every action you want to force the engine to run. But if you are using eXpand you not need the above handling, you could just use the Ids of your actions as Context names and eXpand will force the validation engine to execute
The above code can be used with eXpand 10.2.3 or newer and is hosted at eXpand.ExpressApp.Validation module