SwitchableObject and ObjectFactory.

SwitchableObject and ObjectFactory.

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


bniemyjski posted on Thursday, January 07, 2010

Hello,

I was wondering what the best way is to implement an ObjectFactory that targets SwitchableObject. I say this because a SwitchableObject BO has both DataPortal_xyz and ChildPortal_xyz methods. In this case without ObjectFactory the CSLA Framework manages MarkAsChild() etc. based on if the ChildPortal_xyz method was called.

However, when it comes to ObjectFactory. There is no way to tell whom the sender was and so you have the dilemma of just having the Factory treat the BO as a parent or a child BO.

Thanks
-Blake Niemyjski

rfcdejong replied on Friday, January 08, 2010

We only use the ObjectFactory concept and don't support SwitchableObjects. A ObjectFactory targets one object for one purpose. It's an differend behaviour and u'll have many if (hasParent) then ... else ... which makes the code less readable.

JonnyBee replied on Friday, January 08, 2010

Hi,

ObjectFactory attribute is only checked/valid for DataPortal (root) calls so I would  make separate  factory classes for Root and Child implementation.

ObjectFactory attribute on business object should only address the Root implementation.

Other factories that create/use the object as a child should use the Child implementation.

The challenge would be if you are using LazyLoading as Child -  then you would have to send a parameter in criteria to tell factory to call MarkAsChild or not.

bniemyjski replied on Friday, January 08, 2010

Hello,

I understand the need for Child and Root ObjectFactorys but that is not the point. I have a SwitchableObject and I do not want a hacked solution. Also how would I use Object Factory for Child and this one for Root calls? I really don't think creating two separate ObjectFactorys is the right solution. Also one would not add two ObjectFactory Attributes for Child and Parent. If the only correct answer is "This is not supported for SwitchableObject's" then I would say we all need to go back to the drawing board.

A possible workaround could potentially be setting a IsChildPortalCall property in the Factory Methods right before the DataPortal or ChildPortal method calls are made. Then check this in our ObjectFactory and call MarkAsChild() if IsChildPortalCall is true.

Thanks
-Blake Niemyjski

JonnyBee replied on Friday, January 08, 2010

Hi,

When using DataPortal.Fetch/Create/Update/Delete these are routed to the Server.DataPortal that checks for ObjectFactoryAttribute and if found routes the call to the actual ObjectFactory.

The DataPortal.ChildXYZ methods routes call to Csla.Server.ChildDataPortal and this portal does NOT check for ObjectFactory attribute so these methods are not valid when you are using ObjectFatory.

So when the Switchable object is a child - it only exists in the context of anther root object - and that root has its own ObjectFactory. And this ObjectFactory should call the ChildObjectFactories for the child create/fetch/update/delete calls.

Thus, my key point is: ObjectFactoryAttribute is applicable only for calls routed through the Csla.DataPortal.XYZ - normally used for Root objects. But there is also the special case for LazyLoaded objects where a Child list/object implements its own fetch (calls DataPortal.Fetch as a root object but needs to be marked as child).



bniemyjski replied on Friday, January 08, 2010

Hello,

Do you guys have an example of how to use SwitchableObject in this manner. Also an example of using Child BO's with Object Factory. I thought even the ChildPortal methods went through the ObjectFactory. At least this is how I understood it from the Tracker application and the book.

Thanks
-Blake Niemyjski

RockfordLhotka replied on Friday, January 08, 2010

bniemyjski:
Hello, Do you guys have an example of how to use SwitchableObject in this manner. Also an example of using Child BO's with Object Factory. I thought even the ChildPortal methods went through the ObjectFactory. At least this is how I understood it from the Tracker application and the book. Thanks -Blake Niemyjski

The data portal doesn't do anything with child objects when you are using the ObjectFactory model.

When a root object says it wants to use an ObjectFactory, the data portal defers everything, and I mean everything, to the ObjectFactory - putting all responsibility for creating, populating and manipulating the entire object graph in the hands of the ObjectFactory.

In other words, there's no "child data portal" functionality when you use ObjectFactory.

The reason for this is that the long-term intent of ObjectFactory is to support ORM tools, and they'll create or persist an entire object graph all by themselves. So the data portal assumes the ObjectFactory is fully self-sufficient and all-powerful.

bniemyjski replied on Friday, January 08, 2010

Hello,

I understand this concept... But there are some places where this doesn't make sense and it is a real PITA to do CRUD on CSLA Child Types without the ChildPortal calling into ObjectFactory... When you have multiple BO's that access or interact with the child via relationships. I would think that the ChildPortal methods would still call into the factory.. Otherwise you get ChildPortal_xyz not found... Do you have any real world examples of this in action?

Thanks
-Blake Niemyjski

RockfordLhotka replied on Friday, January 08, 2010

I think the answer here isn't in the data portal, it is in an enhanced
ObjectFactory. There's nothing stopping people from creating more
powerful/specialized subclasses of ObjectFactory - including ones that would
help manage child objects in the object graph.

bniemyjski replied on Friday, January 08, 2010

Hello,

I'm willing to take the time and create complex classes to do this... But I wan't to get a complete understanding first as the way I see it, is not the way it is implemented... So your Child BO's should not have a ObjectFactory Attributes or implement any ChildPortal methods.

The Parents should be calling into methods like this ChildBONameFactory.Update()? I'm pretty sure I tried this scenario and it said ChildPortal was not implemented.

This is still pretty annoying considering the fact that if you are using a SwitchableObject we are on our own....

Thanks
-Blake Niemyjski

rxelizondo replied on Friday, January 08, 2010

I am nowhere near of being an expert on this subject but if I could be of any help...

bniemyjski:

So your Child BO's should not have a ObjectFactory Attributes or implement any ChildPortal methods.


I believe this is true, as far as I know, that is the whole point of the object factory. You are responsible to completely instantiate and perform all CRUD operations outside the business object (Root or child). Its just as simple as that, complete separation of concerns. So you only need that attribute on one object (root object).

bniemyjski:

The Parents should be calling into methods like this ChildBONameFactory.Update()? I'm pretty sure I tried this scenario and it said ChildPortal was not implemented.


Well, it depends on what the "ChildBONameFactory.Update()" method its doing internally, If its calling "DataPortal.Update()" internally in that method then that is wrong.


bniemyjski:

This is still pretty annoying considering the fact that if you are using a SwitchableObject we are on our own....


I am not sure I am getting this. When you let the CSLA manage your CRUD operation you have to tell the framework one way or another when to create a root and when to create a child object. The reason for this is because the CSLA is managing the objects for you.

In the case of an object factory, you are in charge, you can make the object a root, child or whatever you want. You don't have to get permission from the CSLA nor do you have to tell the CSLA what to you, you are in control, you are the man!

bniemyjski replied on Friday, January 08, 2010

Well, it depends on what the "ChildBONameFactory.Update()" method its doing internally, If its calling "DataPortal.Update()" internally in that method then that is wrong.

No it would just be calling an internal method to update the child object...


" am not sure I am getting this. When you let the CSLA manage your CRUD operation you have to tell the framework one way or another when to create a root and when to create a child object. The reason for this is because the CSLA is managing the objects for you.

In the case of an object factory, you are in charge, you can make the object a root, child or whatever you want. You don't have to get permission from the CSLA nor do you have to tell the CSLA what to you, you are in control, you are the man!"

In some cases for example in our PetShop sample application that uses CSLA, we have a few switchable objects that both act as a Parent and as a Child. My point is I know that I have complete control but in this scenario I don't know if I should be calling MarkAsChild or not because theres no way to know if ChildPortal or DataPortal is making the call. With this said we know that ChildPortal call is never made so how does this scenario work.. In essence it doesn't...

RockfordLhotka replied on Friday, January 08, 2010

bniemyjski:
My point is I know that I have complete control but in this scenario I don't know if I should be calling MarkAsChild or not because theres no way to know if ChildPortal or DataPortal is making the call.

There is no child data portal when using the ObjectFactory model.

It seems to me that your switchable object will have a factory class.

That factory class will have a Fetch() method that is invoked by the data portal in the case that the object is being loaded as a root.

But if the switchable object is going to be a child, it is the parent object's factory that will (I assume) be calling the switchable object's factory. I'd recommend that you accept a simple convention of having the parent object call a FetchChild() method on the switchable factory. That FetchChild() might look like this:

public Switchable FetchChild()
{
  var result = Fetch();
  MarkAsChild(result);
  return result;
}

This way you reuse the existing root Fetch(), but clearly acknowledge that this object is a child in this scenario.

The data portal would never call FetchChild() - so FetchChild() would only be invoked from the parent object's factory in the case that Switchable was to be a child.

bniemyjski replied on Friday, January 08, 2010

Hello,

This is what I'll do, thanks!

Thanks
-Blake Niemyjski

Copyright (c) Marimer LLC