MarkAsRoot for BusinessBase, BusinessListBase

MarkAsRoot for BusinessBase, BusinessListBase

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


MarkOviedo posted on Monday, May 10, 2010

In our Silverlight application, we are retrieving POCO domain objects from our database on the server, and then converting them to CSLA-based view models for return to the client. We utilize AutoMapper to create these CSLA view models and map the property values from the associated domain object.

AutoMapper orchestrates much of the complexity of heirarchical object construction for us. However, there is one wrinkle we need to manage for heirarchical CSLA objects, which is the MarkAsChild() for all child objects in the heirarchy.

We have found that the easiest way to accomplish this is to have our own ViewModelBase/ViewModelListBase that inherits from BusinessBase/BusinessListBase. In our base classes, we invoke MarkAsChild for each object in the constructor, thus defaulting each created view model to child. Then for the one parent of the heirarchy that is returned from AutoMapper, we invoke parent.MarkAsRoot().

To enable this behavior, we added the following method to BusinessBase and BusinessListBase :

protected void MarkAsRoot()    {         _isChild = false;    }

This obviously becomes a maintenance issue for us now, as we upgrade CSLA in the future. We could have folded this method into our own view model base classes, but _isChild is private.   :(  Is it possible to add something equivalent to the framework, or yield _isChild in some form that it is accessible in derived classes?

RockfordLhotka replied on Monday, May 10, 2010

I recommend (as a general rule) that people put their own base class between the CSLA base classes and their own types. Havng a base class in between is the primary extensibility model for CSLA.

[Serializable]
public class MyBusinessBase<T> : Csla.BusinessBase<T> where T : MyBusinessBase<T>

In your case you might create different base classes for root and child types - which is fine. But you shouldn't need to alter CSLA to do this - your base classes should continue to function over time as CSLA changes (within limits of course).

MarkOviedo replied on Monday, May 10, 2010

Thanks for the response. As far as I could tell, there was no way to set the _isChild field of the BusinessBase, BusinessListBase = false since it is a private field, and there was no property or method exposing it to the derived class. Thus I resorted to adding the method to the base. If _isChild was protected, I could have manipulated it in the derived class, but it would seem to violate encapsulation.

I definitely need to manipulate the _isChild value of the base class, since that flag is used internally for decision making. Am I missing something?

RockfordLhotka replied on Monday, May 10, 2010

The value is not protected because an object must be a root or child and that can't change during the object's lifetime. That value must be set as the object is created.

The value defaults to false (root), and you can use MarkAsChild() to set it to true (child) as the object is created.

Changing the value after the object is created isn't a valid scenario. If I make IsChild have a protected setter I'll just have support issues forever as people think it is valid to manipulate the value.

So there's exactly one, very limited, way to manipulate the value, which is to set it to true by calling MarkAsChild() - and that is something that's normally handled by the data portal so you don't have to worry about it.

But you are clearly doing something outside the normal scope of CSLA, and so you are in unsupported territory. Still, the choice must be made as the object is created.

Copyright (c) Marimer LLC