Undoing Undo

Undoing Undo

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

Mark Sulkowski posted on Monday, January 31, 2011

I'm reviewing CSLA, and I have concerns that CSLA might not scale well for large object graphs, since the N-Level Undo feature takes snapshots of property values, which may consume an inconvenient amount of time and memory.

I notice that the IUndoableObject interface is implemented by BusinessListBase, and the methods are simply declared as private.  This suggests that it may be difficult to "undo Undo".

Are there ways around using the Undo feature without tinkering with the CSLA code?  Is there an easy way to deactivate or ignore the feature?

Also, what approaches have users successfully taken to write alternative Undo features of their own?  For instance, has anyone written code to remember changes and undo only those, instead of relying on snapshots?  Or perhaps taking a partial undo approach by only restoring deleted rows?


Mark Sulkowski

JonnyBee replied on Monday, January 31, 2011

You can "turn off" the BeginEdit, CancelEdit and ApplyEdit from IEditableObject by setting the flag

DisableIEditableObject = true;

in your editable BOs construcor.

The CustomFieldData project from Jason Bock (also available at http://cslcontrib.codeplex.com) may be further enhanced to provide an alternate undo mechanism. It will keep the "old" values for comparison to determin if object is actually changed.




Mark Sulkowski replied on Monday, January 31, 2011


Rockford Lhotka writes in Expert C# 2008 Business Objects that:

"I don't recommend disabling the interface.  If you disable it, data binding will not be able to interact with your object as it expects, and you may have to write extra UI code to compensate."

In what way would data binding go wrong?  What would this extra UI code have to do in order to compensate?


Mark Sulkowski

JonnyBee replied on Monday, January 31, 2011

"System.ComponentModel.IEditableObject Provides functionality to commit or rollback changes to an object that is used as a data source.
This interface is typically used to capture the BeginEdit, EndEdit, and CancelEdit semantics"

So this is one of the interfaces used by DataBinding, read mora about it in DataBinding FAQ

Using DataBinding:
before you enter the field calls BeginEdit
* if you pres ESC to cancel edit, calls CancelEdit
* If you press TAB and enters a new fiield that has CausesValidation = True , calls EndEdit before entering the new field ( and a new DataBinding, repeat steps)

These calls happends "behind the curtain" as part of DataBinding.

ajj3085 replied on Tuesday, February 01, 2011

Usually you end up with large object graphs because you're modeling you objects based on data and no use case.  Will a user ever modify a property on 400 objects in a single graph?  I really doubt it.  Even once you got your model's properly matching your use case, there are times where you think all child objects must be part of the root, but they really don't.  In Csla, you save the root, and it's children can never be saved independently; they're always saved within the context of the root.  For example, I once had a Contact object with a ContactNotes collection.  The notes always were part of the contact.  I realized in time that this was an arbirtrary, notes didn't need to only be saved with a contact, each note could be created, edited and deleted completely indepedently.

I did it because a note was always related to a contact (ie. thinking in database terms), but my users don't care if a note's lifecycle is outside the contact's or not (in fact, they didn't use them nearly as often as changing the contact addresses and other information).

So before you think large graphs will be a problem, really think through.. do you even need such large graphs for any individual use case?  Probably not.  Uses only work with small sets of discrete information at a time typically.

Copyright (c) Marimer LLC