Parent property was not initialized during DataPortal_Create() when CheckRules() is called

Parent property was not initialized during DataPortal_Create() when CheckRules() is called

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


William posted on Saturday, March 07, 2009

I am using CSLA .NET version 3.0.5 in my project. I have the following parent-child class structure.

RootBO -> ChildBOList -> ChildBO

In ChildBO, there is a factory method to create a new ChildBO instance.

// ChildBO
internal static ChildBO NewChildBO()
{
    return DataPortal.Create<ChildBO>(new Criteria());
}


And, in ChildBOList, I overriden AddNewCore() so that the client application can use AddNew() to get/add a new instance of ChildBO.

// ChildBOList
protected override object AddNewCore()
{
    ChildBO obj = ChildBO.NewChildBO();
    Add(obj);
    return obj;
}

Back in ChildBO, as the factory method is calling DataPortal.Create(), it has the corresponding DataPortal method:

protected virtual void DataPortal_Create(object critera)
{
    // Initialize object variables.
    _property1 = 0;
    ...

    this.ValidationRules.CheckRules();
}

The last statement in DataPortal_Create() executes all the validation rules. What happens in my scenario is that some of the validation methods depends on certain information in RootBO for proper validation. For instance, I use the following:

private static bool ValidationRule1(ChildBO sender, RuleArgs e)
{
    RootBO parent = sender.Parent as RootBO;
    if (parent != null)
    {
        if (parent.Field1 == 0)
        {
            ...
        }
    }
}

This does not work well because the Parent property was not set when the validation rule is invoked during object instantiation, i.e. DataPortal_Create() but only after ChildBO is added into the ChildBOList collection.

What is the recommended approach to design/handle this scenario?

Please advise.
Thanks.

RockfordLhotka replied on Sunday, March 08, 2009

There's not much CSLA could do differently. Since you are using the data portal to create the child, the child could be created on a server - totally disconnected from the rest of your object graph - and so it can't be connected to the object graph until the creation process is complete and the object is known to be in the same physical location as the rest of the object graph.

You'll probably need to make your rules smart enough to realize the parent reference isn't there so they don't blow up, and then re-invoke CheckRules() after you've integrated the new child into your object graph.

William replied on Monday, March 09, 2009

Rocky,

This is the approach I am using my project to connect back the disconnected objects.
Again, thanks for the comments.

Michael replied on Tuesday, September 29, 2009

Hi Rocky

I often need to initialise values for new and fetched objects based on parent values. In Core.BusinessBase I would appreciate something like protected virtual void OnParentSet()
.

Regards
Michael

Copyright (c) Marimer LLC