Hi, I would assume that the business/validation rules for dependent properties would also trigger validation of their dependent properties (regardless of BypassPropertyChecks). At least in cases where the business rule is used to change a property's value. Example: Text change triggers ToUpper to update UpperText. The change of UpperText should than trigger Reverse to update ReverseUpperText. Last update is only performed if I remove the BypassPropertyChecks from ToUpper.
Question: is this intended behavior? Why?
Code:
public class MyObject : BusinessBase<MyObject>{
private static PropertyInfo<string> TextProperty = RegisterProperty<string>(c => c.Text); public string Text{
get { return GetProperty<string>(TextProperty); } set { SetProperty<string>(TextProperty, value); }}
private static PropertyInfo<string> UpperTextProperty = RegisterProperty<string>(c => c.UpperText); public string UpperText{
get { return GetProperty<string>(UpperTextProperty); } private set { SetProperty<string>(UpperTextProperty, value); }}
private static PropertyInfo<string> ReverseUpperTextProperty = RegisterProperty<string>(c => c.ReverseUpperText); public string ReverseUpperText{
get { return GetProperty<string>(ReverseUpperTextProperty); } private set { SetProperty<string>(ReverseUpperTextProperty, value); }}
protected override void AddBusinessRules(){
base.AddBusinessRules();ValidationRules.AddRule<
MyObject>(ToUpper, UpperTextProperty, -1);ValidationRules.AddDependentProperty(TextProperty, UpperTextProperty);
ValidationRules.AddRule<
MyObject>(Reverse, ReverseUpperTextProperty, -1);ValidationRules.AddDependentProperty(UpperTextProperty, ReverseUpperTextProperty);
}
private static bool ToUpper<T>(T target, global::Csla.Validation.RuleArgs e) where T : MyObject{
using (target.BypassPropertyChecks){
target.UpperText = target.Text.ToUpper();
}
return true;}
private static bool Reverse<T>(T target, global::Csla.Validation.RuleArgs e) where T : MyObject{
using (target.BypassPropertyChecks){
target.ReverseUpperText =
new string(target.UpperText.ToCharArray().Reverse().ToArray());}
return true;}
public MyObject() { /* I know this is not CSLA like! */ }}
[
TestMethod] public void MyObject_CascadingRules(){
MyObject obj = new MyObject();obj.Text =
"Hello world!"; Assert.AreEqual("Hello world!", obj.Text); Assert.AreEqual("HELLO WORLD!", obj.UpperText); Assert.AreEqual("!DLROW OLLEH", obj.ReverseUpperText);}
Thanks, however....
* And when the ValidationRules for a property it depends on are checked!
That's what I am pointing at. This is only performed for the 1st level of dependents. Now that I learned from Rocky's video 5 that validation rules can also be used as business rules that update a property's value, I would expect that in such cases the ValidationRules of the dependent's dependents should also be checked (which of course is only useful when the property did change). This should (imo) not have to be triggered by a PropertyHasChanged nor handled by a manual invoke as suggested by JonnyBee.
This of course was a simplified example (I could also have made ReverseUpperText dependent on Text and set the priorities properly). In this case it is rather easy to get the desired result.
What I am trying to do is provide a generic conditional value/expression mechanism. That should allow the developer to specify a condition (Expression<Func<T, bool>>) and a value (Expression<Func<T, [property type]>>). Those expressions are than 'parsed' for the dependencies. The developer using that mechanism shouldn't be bothered about cascading dependencies and my generic code shouldn't have to detect them either (I think ;-).
Copyright (c) Marimer LLC