Bug in Csla 3.5.1?

Bug in Csla 3.5.1?

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


jureleskovec posted on Wednesday, July 09, 2008

I just switched from csla 3.5.0 to the csla 3.5.1 and Undo doesn't work any more:

I do the the following:
1) 'root' (with 'child' is loaded/created). 'root.child' has value other than null (child is a managed field and references an undoable object).
2) Invoke root.BeginEdit()
2) Set root.child = null;
3) Invoke root.UndoChanges()

When trying to reference the 'root.child' it throws the following exception in the 'ReadProperty' method:
Unable to cast object of type 'System.Boolean' to type 'TaskResponsibility'.
in line:
result = (P)data.Value;
and data.Value is 'false' but should instead be object of type 'TaskResponsibility'.



I traced the problem and have seen the following:
1) In the FieldDataManager.CopyState for the 'root' object the 'child' field was not saved into the 'state' storage:
// indicate that there was a value here
state[index] = new FieldData<bool>(item.Name);

2) Later, when I invoked root.UndoChanges() in FieldDataManager.UndoChanges() method wrong value was restored into the 'child' field. So, instead of my previous object the value is 'false'. The following code block clearly shows this:
          if (item != null)
          {
            var undoable = item.Value as IUndoableObject;
            if (undoable != null)
            {
              // current value is undoable
              if (oldItem != null)
                undoable.UndoChanges(parentEditLevel, parentBindingEdit);
              else
                _fieldData[index] = null;
              continue;
            }
          }
          // restore IFieldData object into field collection
          _fieldData[index] = oldItem;


-- Jure

RockfordLhotka replied on Thursday, July 10, 2008

Isn't this the same behavior as you'd get without using a managed field?

UndoableBase has never stored a child object reference as part of the parent's stacked state, because that would cause serialization of the child.

I won't necessarily say this isn't a bug of sorts - but I think this is the behavior that has existed since CSLA .NET 1.0 (more or less).

The problem is, it is a bug that isn't easy to solve. The parent can not store a reference to the child as part of its state, because then the child would be serialized - and that would have a whole host of undesirable side-effects.

It might be possible to address the issue now that child objects are managed fields. Not something I've thought through, but it seems like it should be possible for a FieldData object to do some clever stacking of child object references or something...

jureleskovec replied on Thursday, July 17, 2008

I dug into csla a bit and I can see now what you mean. But this in short means the csla can only cope with fixed businnes object trees.
I think this is a very serious limitation of the framework. Do you see any workaround in a scenario with 'dynamic' BO trees?

If this is the case only with the undo capabilities I will give up my fancy undo button. And I wonder if there are any other issues regarding dynamic BO trees using csla.

-- Jure

RockfordLhotka replied on Thursday, July 17, 2008

I don’t know of a great answer right now, no.

 

The framework supports the concept of the value being null, then being an object, and an undo reverting back to null. That is required for lazy loading, which is why that concept was added.

 

I agree that this is a limitation of the framework, but fwiw you are the first person to bring up the issue in 6 years, so I don’t know how serious it is overall.

 

I’ll add this to the wish list as something to look into at some point.

 

Looking briefly at the IUndoableObject implementation in FieldDataManager, I think it can be done. It will require changes there, and also in FieldData (or creation of a new ChildData perhaps – yeah, that might be more elegant).

 

Having both FieldData and ChildData classes, and making PropertyInfo<T> detect whether a type is a child or not so it can return the right container as needed is half the answer. The goal would be for ChildData to directly implement IUndoableObject.

 

Then changing FieldDataManager’s CopyState() and UndoChanges() methods to see if item is IUndoableObject rather than item.Value would be the next step. That way the undo call would cascade into ChildData, rather than directly into the child.

 

This would allow ChildData to maintain its own (nonserialized) stack of child references AND to cascade the undo calls to the real child object as necessary.

 

I’m sure there are complexities and quirks to be found here – but at a high level I suspect this is the solution.

 

Rocky

 

 

From: jureleskovec [mailto:cslanet@lhotka.net]
Sent: Thursday, July 17, 2008 1:33 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Bug in Csla 3.5.1?

 

I dug into csla a bit and I can see now what you mean. But this in short means the csla can only cope with fixed businnes object trees.
I think this is a very serious limitation of the framework. Do you see any workaround in a scenario with 'dynamic' BO trees?

If this is the case only with the undo capabilities I will give up my fancy undo button. And I wonder if there are any other issues regarding dynamic BO trees using csla.

-- Jure


Copyright (c) Marimer LLC