Best practices for cascading update from one property to another?

Best practices for cascading update from one property to another?

Old forum URL: forums.lhotka.net/forums/t/3824.aspx


rsbaker0 posted on Thursday, November 01, 2007

We have a situation where an update to one property should cause a related/linked property to be set automatically to a specific value.

The dependant property validation rules seem to work fine to enforce the relationship between the two and prevent invalid combinations from being saved, but there are cases where I'd like an update to one to automatically set the other one internally in the object.

Is it OK to use the property setter of the other property while one property is being updated, or should I access the field for the other property directly?

(I know this might seem unusual, but we're migrating an existing product to CSLA and doing this differently would be a breaking change).

ajj3085 replied on Thursday, November 01, 2007

I don't see a problem just changing the field; you probably would want to raise two propertychanged events though, one for each changed property.

rsbaker0 replied on Thursday, November 01, 2007

OK, but I'm also willing to use the property setter itself if that wouldn't cause trouble. It would of course fire both dependant validation rules, but then the PropertyChanged() call in the original setter would cause them to refire again.

Also, is it kosher to change a property during the execution of a validation rule? (e.g. Rule detects something isn't right, but can fix it benignly...)

ajj3085 replied on Thursday, November 01, 2007

Actually that might bite you.  I used to load instance that way in the DP_F, and it did end up causing some problems. 

DavidDilworth replied on Friday, November 02, 2007

I would suggest that you leave the public property getter/setter methods for what they are intended for - public general purpose usage.

It sounds to me like you've got a special use case.

So why not implement special "internal" methods that know about the relationship between the objects.  That way you are in complete control of what fields you want to change and you can manage the relationship how you like.

rsbaker0 replied on Friday, November 02, 2007

I do have all the access I need to the internals, but I'll need to raise "OnPropertyChanged()" for the related property anyway so that the change will be visible to the UI, and that any related validation rules will fire, so it seems like almost all of the side-effects of calling the property setter would occur anyway.

Also, our application uses "changed values concurrency", and we capture the original values of the property being changed via the property setter so that the DAL can apply the appropriate conditions when generating the update SQL, so that's something else I would have to worry about.

I can certainly implement an "InternalPropertySet()" method -- in fact only one would be needed for our entire object layer, I'm just not sure what it would do different than the public property setter.

DavidDilworth replied on Friday, November 02, 2007

It sounds like you should just use the setter for the other property then.  Assuming your setter code looks something like this:

set
{
   if (_value != value
)
   {
      // Change the value of the field...
      _value = value
;
      PropertyHasChanged(
"MyProperty"
);

      // Set a new value into the other property...
      MyOtherProperty = someValue;
   }
}

I don't think that you should have a problem.  Unless of course you've got some kind of dual-dependency in the second property that refers back to the first one Confused [8-)]

 

rsbaker0 replied on Saturday, November 03, 2007

^^^^

This illustrates the crux of what I'm trying to understand.  It's not clear to me whether or not to set the dependant property before or after calling PropertyHasChanged().

Dual-dependencies are indeed tricky. I think this will only work in one direction (unless the dependency naturally short-circuits what would otherwise be runaway recursion).

 

ajj3085 replied on Monday, November 05, 2007

I think that almost always you should call PropertyHasChanged as the last steps; update all your values first, then call those methods.  The reason is that the first value you change may be valid with the current value of the second field, but not valid if the second field has some other value. 

jfreeman replied on Tuesday, September 02, 2008

Based on the newest version of the framework, is the property getter/setter the best place to make changes to related fields?  For instance, if property 1 is changed by the user, I want to re-calculate property 2 based on the contents of th property 1 and property 3 (property 2 = property 1 X property 3).  Anyone have an example of the best way to handle this?  Thanks.

Jonathan

sergeyb replied on Tuesday, September 02, 2008

I usually write a small method that does recalculations and raises PropertyChanged events for recalculated properties, and call it from all three setters.

 

Sergey Barskiy

Principal Consultant

office: 678.405.0687 | mobile: 404.388.1899

Magenic ®

Microsoft Worldwide Partner of the Year | Custom Development Solutions, Technical Innovation

 

From: jfreeman [mailto:cslanet@lhotka.net]
Sent: Tuesday, September 02, 2008 4:39 PM
To: Sergey Barskiy
Subject: Re: [CSLA .NET] Best practices for cascading update from one property to another?

 

Based on the newest version of the framework, is the property getter/setter the best place to make changes to related fields?  For instance, if property 1 is changed by the user, I want to re-calculate property 2 based on the contents of th property 1 and property 3 (property 2 = property 1 X property 3).  Anyone have an example of the best way to handle this?  Thanks.

Jonathan



jfreeman replied on Tuesday, September 02, 2008

Sergey,

Thanks for the quick reply.  Can you post an example of what that looks like and how it is called?  Thanks.

Jonathan

sergeyb replied on Tuesday, September 02, 2008

Something like this…

 

Public int Property1

{

Get {return GetProperty<int>(Poperty1Info)}

Set {SetProperty<int>(Property1Info, value); RecalcProps();}

}

 

Public int Property2

{

Get {return GetProperty<int>(Poperty2Info)}

Set {SetProperty<int>(Property2Info, value);}

}

 

 

Public int Property3

{

Get {return GetProperty<int>(Poperty3Info)}

Set {SetProperty<int>(Property3Info, value); RecalcProps();}

}

 

 

Private void RecalcProps()

{

  Property2 = Property1 * Property3

}

 

Sergey Barskiy

Principal Consultant

office: 678.405.0687 | mobile: 404.388.1899

cid:_2_0648EA840648E85C001BBCB886257279
Microsoft Worldwide Partner of the Year | Custom Development Solutions, Technical Innovation

 

From: jfreeman [mailto:cslanet@lhotka.net]
Sent: Tuesday, September 02, 2008 4:47 PM
To: Sergey Barskiy
Subject: Re: [CSLA .NET] RE: Best practices for cascading update from one property to another?

 

Sergey,

Thanks for the quick reply.  Can you post an example of what that looks like and how it is called?  Thanks.

Jonathan



Copyright (c) Marimer LLC