Intercept PropertyChange with access to old and new values
Intercept PropertyChange with access to old and new valuesOld forum URL: forums.lhotka.net/forums/t/8327.aspx
bartol posted on Monday, January 11, 2010Hi,
In my scenario I need to call a method when a property changes but to pass that method both the old value and the new value of the property. I tried a couple of options (detailed below) but I wonder if this functionality is part of the framework (could not find anything in the book or forum):
1. Call the method inside the property setter
2. Override both OnPropertyChanging and OnPropertyChanged caching the old value and calling the method on Changed.
The first method does not work for me because the properties are generated from a table in the database and I would need to remember to change them every time the structure of the table changes. The second one works but it is obviously a workaround.
Is this functionality somewhere else in CSLA?
RockfordLhotka replied on Monday, January 11, 2010
The only support for this comes in the form of a custom FieldData object you can create. This is also the technique used to alter the behavior of IsDirty, and you can find some information on that in the FAQ
rxelizondo replied on Monday, January 11, 2010Hi Rocky,
I know there are bigger fish to fry right now so I don’t see this happening any time soon (if ever) but…
Wouldn’t you agree that having a built in FieldData that could handle Original/Current values and whose IsDirty property was based on weather the original value is different that the current value would be a pretty awesome addition to the CSLA?
Sure, I realize that we can achieve this already by extending the CSLA but man, being able to switch behaviors with a simple configuration value would be really great and the framework would probably cover 95% of the the FieldData needs out there.
Just a though but something tells me that you have looked into this and there is a good reason why this is not built in.
JoeFallon1 replied on Thursday, January 14, 2010
As best I can recall Rocky objects to the feature due to the "doubling in size" of the serialized BO. (Assuming all properties are changed, etc.)
Some users get around this by using a dictionary of old/new values so only changed values exist in the dictionary. Thus it is only slightly larger than the original BO for just a few changed values.
I agree that there are many scenarios where being able to know the original and current values is extremely valuable. Having it built-in would be a plus in my book. Being able to "turn it off" to keep current optimized speed of serialization should be available for those that do not want or need this feature.
rsbaker0 replied on Friday, January 15, 2010Here is how we solved this problem:
Basically, we maintain a dictionary of original values, but only save the original value when the value is changed. So, the overhead is proportional to the number of changed properties rather than doubling the size of the object.
The dictionary is maintained by an override of OnPropertyChanging(), so anything resulting from the actual property change (business rules, etc.) has access to the original value if needed.
It doesn't really require any changes to CSLA, but might need to be changed if you use Silverlight because it uses reflection to read the original property value.
frankhoffy replied on Friday, July 09, 2010
I'd like to chime in on this a bit too. I've found that the inability to get old values for fields makes it very difficult to do updates in many-to-many relationship scenarios. For instance, I have 3 tables: Note, Issue, and NoteIssue. The NoteIssue table just as a NoteId and an IssueId in it, and combined they make up the primary key. Therefore, there is no way to change the NoteId or the IssueId without having the old values for these columns. Since a delete/add is impractical for my customers, I need to implement this myself.
RockfordLhotka replied on Friday, July 09, 2010
Jason Bock has a blog post where he describes, in detail, how to create a custom FieldData<T> type that tracks old values for more granular IsDirty implementation - but it would also address your requirement I think.
frankhoffy replied on Monday, July 12, 2010
I found the link Rocky, thanks: http://www.jasonbock.net/jb/Default.aspx?blog=entry.9cc70d85bef34e2b9a683ba82615f8a3
There's quite a bit of code involved to accomplish this task. I suspect my fellow programmers will be scratching their heads when they look at the code. I'm probably going to see if my DBA is OK with me using an identity column for the association table.
Perhaps what CSLA needs is some sort of option to enable the caching of old values when it's needed. In my case the actual data stored would just be two ints, so the object would have a very small memory footprint.
I think it would be useful to include an example of this with the CSLA samples. ProjectTracker has an Assignments table that would be a good example.
Copyright (c) Marimer LLC