I have two questions relate with the authorization and the CanWriteProperty implementation:
Q1: Why do you enforce having only one Authorization Rule object per element (property, method, object)? You allow multiple rules objects for Business Rules and Validation Rules, but not for Authorization Rules.
I ask this because I could make use of it allowing multiple Authorization Rules, where the rules are evaluated like an OR (if one is true user has right), and having one rule with multiple roles, where the roles are evaluated like an AND (all must evaluate to true for the rule to be true). This behavior will allow me greater flexibility and I would have to create customs rules only for more complex and less common cases.
Here are 2 scenarios that we were considering (scenario 1 being the most flexible):
· Allow multiple authorization rules per element, which are evaluated as an OR.
· Have the multiple roles per rule be evaluated as an AND.
Rule Object 1(…, Property: IsReviewed, Roles: AssetManager, Reviewer)
Rule Object 2(…, Property: IsReviewed, Roles: Administrator)
· Have 2 classes inherit from AuthorizationRule (1) AuthorizationRuleAND and (2) AuthorizationRuleOR, where each evaluate the multiple roles as an AND or OR depending on the class type used.
RuleAND Object 1(…, Property: IsReviewed, Roles: AssetManager, Reviewer)
RuleOR Object 2(…, Property: Comment, Roles: AssetManager, Administrator)
Q2: There are some scenarios where we would like to throw a more specific/descriptive exception when an authorization rule is broken instead of the generic ___ exception being thrown when the authorization check does not pass. How would you recommend doing that?
One reason for the one rule limit is for performance. When an object is bound to a UI (especially in Windows Forms), the properties can be read very frequently. BusinessBase (by default) caches the result of the rule to minimize how often each rule is run. Although I suppose I could have aggregated and cached the result generated by combining all rules, the whole process of invoking a list of rules and caching the combined result would have overhead.
Another reason is that I would have to arbitrarily choose to AND or OR the results. I'd choose wrong for some subset of users - very possibly you :)
Finally, I don't really need to support more than one rule. You can do that. You can easily create an aggregate rule that is provided with a list of other rules that you execute, and then you combine their results. Because the ultimate result of an authorization check is true or false - a singular value - this aggregate rule technique is easy to implement.
(Unlike business rules, where there are business rules and validation rules, and they have no discrete or singular result, so there's no easy way to aggregate them together. Though having said that, I do want to make it clear that you could implement an aggregate business rule scheme too - it is just a bit more complex - but I discuss having rules run other rules in the Creating Business Objects ebook).
There is no way to do this, because authorization rules don't throw any exceptions. They return true or false. In some cases CSLA will throw an exception due to a false result, but the rules themselves are Boolean. In the most common scenario (property read) no exception is thrown at all (by default).
Copyright (c) Marimer LLC