Csla.ObjectFactory III – What’s wrong with UpdateChildren()

Derick Bailey’s post about Csla vs DDD brought out a simple but very interesting question :

Which one is correct?
Person.AddCertificate(), or Person.Certificates.Add()?

Almost the same? But it turns out the 2nd one is NOT “correct”, at least, not in DDD way.

That’s the problem in CSLA. Always thinking in table, data-centric design/dev. An extreme example, FieldManager.UpdateChildren().

How about save? Person.UpdateEmail() or Person.Email.Update(). [Email.Child_Update() in classic CSLA way.]

CSLA is not an ORM tool/framework, but BO carries all the dirty flags, in fact it’s DataPortal doing all the relationship maintenance work. RootBO.Save() is handling all the updates of its children, through FieldManager.UpdateChildren() jumping into each childBO’s internal private Child_XYZ methods. Handy, “clean”, but it’s not “correct”.This is the exactly same problem when I was trying to switch to the new Csla.ObjectFactory way: I had to keep an extra set of Protal methods in child BO, those child portal method,  to work with Parent BO’s FieldManager.UpdateChildren() method.

What if we ignore FieldManager completely? Just let Person.Save() directly call DataPortal.Update<EmailBO>(person.Email) ? Or DataPortal.Update<TelephoneBOCollection>(person.Telephones) ? Then child BO can still use  the general AbstractFactory which only have root level CRUD methods.

The direction Rocky made in ObjectFactory looks right, child CRUD should be done by root BO.  The thing is, it’s not backwards completable. It’s trying to retire FieldManager.UpdateChildren()!

The update route should be RootBO.Save -> Root Factory.Update -> Child Factory.Update, don’t call child BO’s internal Child_XYZ anymore.

Currently for legacy reason I still keep the following code in my ChildBO to bump calls from parent to child’s own factory, those UpdateChildren() in root BO can be alive for awhile, until I move them to root factory, which should be the newly strongly-typed customized UpdateChildren().


private void Child_DeleteSelf(){ DataPortal.Delete(this);}

private void Child_Insert(IParent parent){
     this.ParentId = parent.Id;
     DataPortal.Update(this);
}

private void Child_Update(){
     var newBO = DataPortal.Update(this);
     DataMapper.Map(newBO, this);
}

It might just looks like a wrapper trick, but those DataPortal calls are actually in Factory class now which indeed is in an external true service layer.

In my app, it’s one AbstractFactory for all BOs, both root and child.

I do have a problem now, where should I put transaction scope attribute? It shouldn’t be a big deal, possible solutions:

  1. Create some extra methods in factory not in transaction Scope dedicated for child methods,
  2. Unit of Work pattern?

Look back Ryan’s ProjectTrackerHybrid code, all the child propertis are not registered! Which means they are not in fieldmanager at all. It’s ORM’s job to handle the realationship UpSet (Update/Insert).

Advertisements

One thought on “Csla.ObjectFactory III – What’s wrong with UpdateChildren()

  1. The objectfactory is good, but it’s hard to understand how the Child functionality stuff works in CSLA itself. It feels like so much more code is needed and parent / child relationship is just more difficult. And still not having a really good solution myself yet.

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