Possible Bug - Insert Item

Possible Bug - Insert Item

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


DCottle posted on Thursday, January 03, 2008

I am using a CSLA BusinessListBase as the Datasource for a Windows.Forms.BindingSource.   That BindingSource is then used as the datasource for the Infragistics UltraWinGrid (7.1, Vol3)

The actual datastructure that is held by the grid is:

BusinessListbase (lvl1)

   BusinessBase (lvl2)

      BusinessListBase (lvl3)

         BusinessBase (lvl4)

 

When adding a row to the grid (lvl4) by clicking on the new template row, CSLA fires the InsertItem method to add the newly created object.  The problem is that the InsertItem method does not set the IsChild = True of the object it just inserted.  If you then leave that row without changing anything, the CancelEdit method is called, and eventually the DeleteChild method is called.  This is where it goes boom.  You cannot call DeleteChild on an object that is not a child.

I may be mistaken in how things are supposed to work.  I am not a newb to CSLA, but I am not nearly as experienced as alot of people here are.  Can somebody please enlighten me as to what may be going wrong here, and why we would not ALWAYS want to set item.IsChild = True when calling the InsertItem method?

RockfordLhotka replied on Thursday, January 03, 2008

The business object developer decides whether the objects are child or not. It is up to you to call MarkChild() in the constructor of a child object.

So your lvl4 class should always be calling MarkChild() in the constructor, because it is clearly a child in your model. So should lvl2 and lvl3. The only root you have is your lvl1 class.

DCottle replied on Thursday, January 03, 2008

Maybe I am a bit confused as to the real meaning of IsChild.

It is my understanding that Ischild is simply a flag to indicate that I have a parent to whom I belong.  If I was inserted via InsertItem into a collection, then I obviously always have a parent.

However, if IsChild is meant to simply be a logical indicator of a relationship between two objects then I understand where you are coming from.  If that is the case though, what do you call an object that is a member of a BusinessListBase and not marked as IsChild=True?  What is that type of object?

 

RockfordLhotka replied on Thursday, January 03, 2008

DCottle:

However, if IsChild is meant to simply be a logical indicator of a relationship between two objects then I understand where you are coming from.  If that is the case though, what do you call an object that is a member of a BusinessListBase and not marked as IsChild=True?  What is that type of object?

Unsupported, or invalid Smile [:)]

CSLA .NET strictly defines objects into a set of categories (stereotypes is a better word):

  1. Editable root
  2. Editable child
  3. Editable root list
  4. Editable child list
  5. Read-only root
  6. Read-only child
  7. Read-only root list
  8. Read-only child list
  9. Name/value list
  10. Command
  11. Dynamic list

Any stereotype with "editable child" in the name must call MarkChild() in the constructor to indicate that the object is logically a child. I chose this approach rather than having two base classes (BusinessRootBase<T> and BusinessChildBase<T> for example), though there are days I think the multiple base classes (one per stereotype) might have been a better option.

Technically there are some other stereotypes:

  1. Switchable
  2. Switchable list

But in my view these indicate (99.9% of the time anyway) a flawed object model. So I usually forget to include them in the list of stereotypes.

DCottle replied on Thursday, January 03, 2008

RockfordLhotka:

   Unsupported, or invalid Smile [:)]

That makes my point exactly.  If it is added via InsertItem then it has to be a child. 

Rather than beat a dead horse, can you tell me this:

If I want to consider items added via InsertItem as always being children, can you see any harm to me making available the MarkAsChild method in the IEditableObject interface and simply calling the item.MarkAsChild from InsertItem?

I realize that the customization would need to be manually ported from one version of CSLA to the next, but since partial classes are available for custom code changes that is a bit easier nowadays...

Thanks,

David

RockfordLhotka replied on Thursday, January 03, 2008

It is important to realize that the coding pattern of parent and child objects are not the same. Look at Chapter 7 for details, but there are differences in how you code a child object from a root object that go far beyond whether MarkChild() is called.

 

If you want an object that can be either a root or child, then you are following the Switchable stereotype. Again, that typically indicates a flawed object model. But if you are satisfied that your model isn’t flawed, and are willing to put in the effort to build a switchable object then go for it.

 

In that case you still don’t expose MarkChild() as public. Instead, you indicate to the object whether it is being created in “root mode” or “child mode” based on how it is created. Typically you have a  root factory that is public and a child factory that is internal/Friend. In your collection’s AddNewCore() override you call the child factory, while other consumers (like the UI) call the public factory.

 

Look at the SwitchableObject template in the csla\templates directory to get some idea how it fits together. To build such an object you need dual factories, dual data access code and dual constructors. This is a supported (though frowned upon) stereotype, and doesn’t require alteration of CSLA.

 

But you must make the determination of root or child at object creation time, because the data access and other behaviors are different for each stereotype. I think you are just asking for trouble if you start switching objects between being root or child in the middle of their lifetimes. Certainly you are well outside the design parameters of CSLA at that point, and thus you are on your own in terms of resolving any issues that occur as a result :)

 

Rocky

 

 

From: DCottle [mailto:cslanet@lhotka.net]
Sent: Thursday, January 03, 2008 11:35 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Possible Bug - Insert Item

 

RockfordLhotka:

   Unsupported, or invalid Smile <img src=">

That makes my point exactly.  If it is added via InsertItem then it has to be a child. 

Rather than beat a dead horse, can you tell me this:

If I want to consider items added via InsertItem as always being children, can you see any harm to me making available the MarkAsChild method in the IEditableObject interface and simply calling the item.MarkAsChild from InsertItem?

I realize that the customization would need to be manually ported from one version of CSLA to the next, but since partial classes are available for custom code changes that is a bit easier nowadays...

Thanks,

David



DCottle replied on Thursday, January 03, 2008

We have taken the time to set up our objects as switchable objects with all of the "duel" stuff that you mentioned.  And I certainly can add the MarkChild call to those constructors.

My only point was that if an item is added to a collection must be a child, then it makes sense to me to put it there instead of having to make sure you get the line of code in every object that will ever be derived from the EditableBusinessBase.

Taken from a different perspective.  Why do you call SetParent in the InsertItem method? You could just as easily make the statement that we should just override the InsertItem method in each of our objects and set the parent there.  It would work, but seems pretty silly to do that when you know your parent at the time it is inserted inside of the base InsertItem(). 

At this point though, I feel as though I am just arguing so I must say thank you for your input and time taken to answer my questions.  I appreciate all you have done for our community.

RockfordLhotka replied on Thursday, January 03, 2008

I do understand what you are saying.

 

However, if I were to do anything, it would be to have InsertItem() throw an exception if you attempt to add a non-child object. In fact you’ve convinced me that this is a good idea, so I’ve added it to the wish list (to throw an exception), because it is true that allowing a root object to be inserted is invalid and really should be prevented.

 

It would be very incorrect to have CSLA simply “make the object a child” when there’s a whole lot of coding that must occur for an object to behave as a child. There’s no way for InsertItem() to know if the developer did implement all that code or it they just messed up by trying to insert a non-child where only a child can go.

 

Silent acceptance of an invalid object is incorrect, but so is silently altering a flag that is supposed to indicate that the developer knew what they were doing :)

 

Rocky

 

 

From: DCottle [mailto:cslanet@lhotka.net]
Sent: Thursday, January 03, 2008 12:15 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: Possible Bug - Insert Item

 

We have taken the time to set up our objects as switchable objects with all of the "duel" stuff that you mentioned.  And I certainly can add the MarkChild call to those constructors.

My only point was that if an item is added to a collection must be a child, then it makes sense to me to put it there instead of having to make sure you get the line of code in every object that will ever be derived from the EditableBusinessBase.

Taken from a different perspective.  Why do you call SetParent in the InsertItem method? You could just as easily make the statement that we should just override the InsertItem method in each of our objects and set the parent there.  It would work, but seems pretty silly to do that when you know your parent at the time it is inserted inside of the base InsertItem(). 

At this point though, I feel as though I am just arguing so I must say thank you for your input and time taken to answer my questions.  I appreciate all you have done for our community.



DCottle replied on Thursday, January 03, 2008

RockfordLhotka:

Silent acceptance of an invalid object is incorrect, but so is silently altering a flag that is supposed to indicate that the developer knew what they were doing :)

 

That is classic.  ;)

Thanks for the lively discussion. 

Copyright (c) Marimer LLC