Csla.ObjectFactory Part II – Difficulties on Child BO

I was wondering  why CslaFactory only needs to implement CRUD, no child methods at all. Other developers post the  same question on forum.

Rocky’s answer made sense, it your own Facotory’s responsibility to handle all those relationship. My specific problem on this is, FiledManager.UpdateChildren() is not available any more.

First, the FieldManager property in BO is protected, this can be fixed by adding new method in our BaseBO to make it public. The root BO changed to CslaFactory then. But, next challenge is, this UpdateChild is not going through DataPortalSelector->DataPortal_XYZ route, it still uses Reflection to look up the ‘Child_XYZ” method right in your child BO, not in CslaFactory class at all!

You have to manage your own update route by looping through all the children from your root BO! Forget the powerful FieldManager.UpdateChildren().

Relationship is built in DAL. ?? When start using DTO, I know it is the dead weakness. The word around is pulling relationship up to Csla BO and rely on those magic UpdateChildren methods. Now, updateChildren is gone, I have to create a real business explicit UpdateChildren.

    public class AbstractObjectFactory : ObjectFactory, IBusinessBaseServerFactory
        where BO : MyBusinessBase
        where TRepository : IRepository
        where DTO : class, new()
    {
        protected IRepository _repository = StructureMap.ObjectFactory.GetInstance();

        public virtual BO NewBO()
        {
            return (BO)Activator.CreateInstance(typeof(BO), true);
            //            return new BO();
        }

        public virtual void InsertChildren(BO bo){}
        public virtual void UpdateChildren(BO bo){}
        public virtual void DeleteChildren(BO bo){}

        public virtual BO Create()
        {
            var obj = NewBO();
            MarkNew(obj);
            obj.GetValidationRules().CheckRules();
            return obj;
        }

        public virtual BO Insert(BO bo)
        {
            var data = _repository.Insert(bo.BuildDTO());
            if (data == null) throw new DataException(“Repository Insert return null.”);
            bo.LoadFromDTO(data);

            InsertChildren(bo);
            // FieldManagar().UpdateChildren(bo) is not through CslaFactory.
//            bo.GetFieldManagar().UpdateChildren(bo);

            return bo;
        }

    public class StakeholderFactory : AbstractObjectFactory
        , IStakeholderFactory
    {
        public override void InsertChildren(StakeholderBO bo)
        {
            // Update Alias Name Child
            var factory = new StakeholderAliasNameFactory();
            for (int i = 0; i < bo.AliasNames.Count; i++)             {                 bo.AliasNames[i] = factory.Insert(bo.AliasNames[i]);             }         } [/sourcecode] This looks weird. And my solution of mocking Parent for testing update Child is useless then, because that assume root BO is calling FiledManager.UpdateChildren. One solution is to  re-write those update children code into my CslaFactory class. More coding, does it look more clear? I’m not sure. One of my root BO has 7+ children, I don’t think it’s worth to move.

Another quick dirty fix might be, still leave those Child_XYZ methods in Child BO for legacy purpose, inside put DataPortal_XYZ to redirect call to CslaFactory. This solution can keep parent update code same as before, still using UpdateChildren(), also the Child BO will look more like a switchable BO.

Enough, now I fully understand Ryan’s statement: Csla is great, but we need relationship.

Look how Ruby and NH dealing with relationship: has_many, belongs_to. Simple and clear.

Advertisements

6 thoughts on “Csla.ObjectFactory Part II – Difficulties on Child BO

  1. The problem I see (which is what I am struggling with) is that the DTO causes the problems with children. Do your DTO’s have the relationships set? Ideally we wouldn’t need the DTO and map the BO directly to NHibernate and NHibernate would handle children (I think)

    What I would like to see are CSLA collections mapping directly to NHibernate collections. There are techniques out there but I don’t have a lot of experience yet of .NET to make it happen.

  2. We are sharing the same pain. I think just adding relationship into DTO is not enough to solve this problem. We also need dirty flags. Then DTO becomes another BO or something LinqTable like Entity class. It’s much easier just ‘map the BO directly to NHibernate and NHibernate would handle children’.

    But, we are not using NHinbernate now. The reason we choose DTO is we thought we can switch to another ORM later with no changes in BL at all.

    Set relationship in BL or ORM, becomes a hard question.

  3. I was under the impression that to switch to another ORM or direct SQL would be the introduction of another ObjectFactory/Repository. Couldn’t the NHibernate DAL not use DTO, but other ORMs will use DTO??.

  4. I was thinking of having the ObjectFactory create the object and return the object. The BO will have nothing in it for data, it will not receive DTO’s. Then if I need to change data access tech I will need to re-write my ObjectFactories.

    BO > ObjectFactory > NHib Repository > MappingBO

    if I need DTO, which I might because of CSLA Collections.

    BO > ObjectFactory > DTO > NHib Repository > MappingDTO

  5. I know Ryan changed CSLA Collections to simple IList.

    I think that was to completely push cascade updating to NH repository. That’s why his Factory only has Update() not Insert() or Delete().

    To continue using Facotry, I must quit using DTO or, add relationship into DTO (nightmare!)

    To merge Csla BO with LinqTable is hard, because Linq2Sql is not as open as NH. It’s time to switch to NH now.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s