CSLA 3.5 SetProperty<P>()

CSLA 3.5 SetProperty<P>()

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


damo posted on Tuesday, March 04, 2008

Hi All,
I've just read & commented Rocky's post regarding the Property Code reduction and it looks good.
I find a lot of the time, in my property setter, I may need to set the private backer of another property or do some calulation before PropertyHasChanged() is called. Otherwise the UI won't pick up the change to the other property. For instance:
set {
  if(_field1 != value){
    _field1 = value;
    _field2 = field1 / 2;
    RecalculateSomething();
    PropertyHasChanged();
}
Looking at CSLA3.5Beta 2 it would appear that this is not possible if using:
set { SetProperty<double>(Field1Property, value); }
So I propose overloading SetProperty to allow a callback delegate to be passed in:
protected void SetPropertyCallback();
protected void SetProperty<P>(PropertyInfo<P> propertyInfo, P newValue, SetPropertyCallback
setPropertyCallback);
And modify BusinessBase.LoadPropertyValue<P>():
if (markDirty) {
    OnPropertyChanging(propertyInfo.Name);
    FieldManager.SetFieldData<P>(propertyInfo, newValue);
    if(setPropertyCallback!= null)
      setPropertyCallback();
    PropertyHasChanged(propertyInfo.Name);
}
(I also propose refactoring the instances where the above code appears into a single private function).

So from a callers perspective, we can do things like this:
set { SetProperty<double>(Field1Property, value, delegate {RecalculateSomething();} ); }
Any thoughts on this?

trives replied on Tuesday, March 04, 2008

If your using managed fields, it's possible to call one of the protected overloads of LoadProperty.  These overloads do not call PropertyHasChanged.  So, you can set your fields using a call to LoadProperty for each field and then call PropertyHasChanged.  The LoadProperty methods do not automatically do any authorization checking, so you might also need to make a call to CanWriteProperty.

damo replied on Tuesday, March 04, 2008

Actually, the overloads seem to be calling the private LoadProperty implementation, so PropertyHasChanged will get called.

Rocky suggested that I create a rule to perform the calculation, but to me, that doesn't seem right - they are called ValidationRules...

trives replied on Tuesday, March 04, 2008

The LoadProperty overloads call the private LoadPropertyValue method with the last parameter, markDirty, equal to false, which prevents the call to PropertyHasChanged.  I haven't actually run any code to test what I suggested, so maybe I'm missing something else.

 

damo replied on Wednesday, March 05, 2008

damo:
Rocky suggested that I create a rule to perform the calculation, but to me, that doesn't seem right - they are called ValidationRules...

I've looked further into this. There is definitely situations where I only want RecalculateSomething() to run only once - when the property private backer has changed. It may be for performance reasons - defining it as a validation rule means that it'll get run whenever CheckRules() is called and if there are several properties doing this there be several unrequired recalculations performed.

Copyright (c) Marimer LLC