CSLA .NET

Vibrant discussion about CSLA .NET and using the framework to build great business applications.

ObjectFactory and Child Objects.

rated by 0 users
Answered (Verified) This post has 1 verified answer | 10 Replies | 3 Followers

Top 50 Contributor
184 Posts
Blake Niemyjski posted on Mon, Apr 5 2010 2:31 PM

Hello,

How should one treat Child Fetch calls when using the ObjectFactory? I have an EditableChild or a ReadOnlyChild and my code looks like this:

 

  internal static SettingGroupList GetByApplicationID(System.Int32 applicationID)

        {

            return DataPortal.FetchChild< SettingGroupList >(

                new SettingGroupCriteria{ApplicationID = applicationID});

        }

It doesn't work because ChildPortal methods are never invoked but I need to call the ObjectFactory Implementation. Should I always just have them call the Regular Fetch? Is there a best practice for this?

        internal static SettingGroupList GetByApplicationID(System.Int32 applicationID)

        {

            return DataPortal.Fetch< SettingGroupList >(

                new SettingGroupCriteria{ApplicationID = applicationID});

        }

 

Thanks

-Blake Niemyjski

Thanks

-Blake Niemyjski (Author of the CodeSmith CSLA templates and CSLA Core team member).

 

Answered (Verified) Verified Answer

Top 10 Contributor
9,270 Posts

The only alternative though, is to implement the fetch (DP_F or factory) and manually call MarkAsChild to make the object a child. Doing that in genned code is probably fine, but doing it manually is not fine because people forget and then have hard to resolve bugs. Those bugs drove me to create the child data portal concept - it was just such a common issue that I felt it needed solving Smile

Rocky

All Replies

Top 10 Contributor
9,270 Posts

The child data portal is not compatible with the object factory.

When using the object factory model, the factory is responsible for creating and initializing child objects as well as root objects.

You might consider having the root object factory create and invoke other "child" object factories - but this isn't something the data portal will do for you. When you are in object factory land, you are on your own.

Rocky

Top 50 Contributor
184 Posts

Hello,

I understand this completely. What I'm asking about is if you are lazy loading children and you know how you want to load the child during runtime (not during compile time). Would the best approach be to call Fetch<>() instead of FetchChild<>() in your children's Get Methods as this will invoke Object Factory.

Thanks

-Blake Niemyjski

Thanks

-Blake Niemyjski (Author of the CodeSmith CSLA templates and CSLA Core team member).

 

Top 10 Contributor
9,270 Posts

The simplest way to lazy load child objects is to use a command object (or readonlybase object) to do the work. Basically create it as a unit of work - where that work is to run to the server, load the child object(s) and return the result.

Then the lazy load code can just Fetch() the ROB, and grab its Results property value to get the child objects. This way the child objects don't get complex - they remain purely children, and any complexity is shifted up into the ROB parent that is retrieving them - and even that isn't complex right, just open the database, do the query and call FetchChild() to get each child.

Rocky

Top 50 Contributor
184 Posts

Hello,

It wouldn't be that hard to update this to use that method of retrieval, just seems like a lot of extra work for preexisting functionality.

Thanks

-Blake Niemyjski

Thanks

-Blake Niemyjski (Author of the CodeSmith CSLA templates and CSLA Core team member).

 

Top 10 Contributor
9,270 Posts

The only alternative though, is to implement the fetch (DP_F or factory) and manually call MarkAsChild to make the object a child. Doing that in genned code is probably fine, but doing it manually is not fine because people forget and then have hard to resolve bugs. Those bugs drove me to create the child data portal concept - it was just such a common issue that I felt it needed solving Smile

Rocky

Top 50 Contributor
184 Posts

 

Hello,

Thats what I'm currently doing Smile. I think I'll just detect if they are using object factory and if they are I'm going to output a comment saying this normally is FetchChild<>() but were calling Fetch<>() so the data portal is invoked. If your class is not marked as a child then you changed the object factory implementation Smile.

Thanks

-Blake Niemyjski

 

Thanks

-Blake Niemyjski (Author of the CodeSmith CSLA templates and CSLA Core team member).

 

Top 50 Contributor
184 Posts

Hello,

This has been fixed in the latest nightly build of the CSLA templates.

Thanks

-Blake Niemyjski

Thanks

-Blake Niemyjski (Author of the CodeSmith CSLA templates and CSLA Core team member).

 

Top 50 Contributor
184 Posts

Can we do something to change this behavior in CSLA 4.5? I just ran into this again where ChildPortal (CreateChild) wasn't using the ObjectFactory method which I thought it would use (it's been a while). Instead of calling the Create Method in OF it created a new instance locally. I understand that these ChildPortal calls should only happen locally...

My idea is that if you say all my creation logic is going to be in this assembly (which is more than likely on the client), then make the call to object factory for the creation.

Thanks

-Blake Niemyjski (Author of the CodeSmith CSLA templates and CSLA Core team member).

 

Top 10 Contributor
9,270 Posts

You are suggesting that the child data portal look for the ObjectFactory attribute and route the call through the regular data portal to the factory if it is present?

Rocky

Top 500 Contributor
27 Posts

I slight aside but think I am on the same subject. I ran in to this bug when unit testing some generated code. I changed the property of the parent that held Identification for the child to a different child. The test was to check if the load child was now the new value but it failed.

The copy of the example from "Using CSLA" leaves out that there is usually a query for children by a property value.

If it is a Many to One relationship something like ChildId with a backing field _childIdProperty.

I suggest it read something like:

if((!FieldManager.FieldExists(AddressesProperty)) || (!FieldManager.IsFieldDirty(_childIdProperty))

Thanks,

Charles

 

Example

In Creating Business Objects you have:

public static readonly PropertyInfo<AddressEditList> AddressesProperty =

RegisterProperty<AddressEditList>(c => c.Addresses,

RelationshipTypes.Child | RelationshipTypes.LazyLoad);

public AddressEditList Addresses

{

  get

{

if (!FieldManager.FieldExists(AddressesProperty))

{

LoadProperty(AddressesProperty, null);

AddressListCreator.GetAddressListCreator((o, e) =>

{

if (e.Error != null) throw e.Error; else Addresses = e.Object.Result; });

}

return GetProperty(AddressesProperty);

}

 

 

 

 

 

 

Page 1 of 1 (11 items) | RSS

Copyright (c) 2006-2010 Marimer LLC. All rights reserved.
Email admin@lhotka.net for support.
Powered by Community Server (Non-Commercial Edition), by Telligent Systems