Using business rules to create a child object

Using business rules to create a child object

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


Chris62 posted on Thursday, January 26, 2012

I have a parent object that depending on some business logic should create a child.

 

public class ParentClass : BusinessBase<ParentClass>

{

private readonly static PropertyInfo<int> SomeIdProperty = RegisterProperty<int>(prop => prop.SomeId, "Some Id);

public int SomeId

{

get { return GetProperty(SomeIdProperty); }

set { SetProperty(SomeIdProperty, value); }

}

 

private readonly static PropertyInfo<ChildClass> ChildObjectProperty = RegisterProperty<ChildClass>(prop => prop.Child, "Child Object");

public ChildClass Child

{

get 

{

if (!FieldManager.FieldExists(ChildObjectProperty))

{

LoadProeprty(ChildObjectProperty, DataPortal.CreateChild<ChildClass>());

}

return GetProperty(ChildObjectProperty); 

}

set { SetProperty(ChildObjectProperty, value); }

}

// factory methods

protected override void AddBusinessRules()

{

BusinessRules.AddRule(new ChildCreateRule(SomeIdProperty, ChildObjectProperty));

}

private class ChildCreateRule : Csla.Rules.BusinessRule

{

public ChildCreateRule(PropertyInfo PrimaryProperty, PropertyInfo ChildProperty)

: base(PrimaryProperty)

{

InputProperties.Add(PrimaryProperty);

InputProperties.Add(ChildProperty);

}

protected override void Execute(Csla.Rules.RuleContext context)

{

base.Execute(context);

int id = (dynamic)context.InputPropertyValues[InputProperties[0]];

if(id > SomeNumberCriteria)

{

ChildClass kid = ChildClass.NewChildClass();

IPropertyInfo childInfo = InputProperties[1];

context.AddOutValue(childInfo, kid);

}

}

}

// dataportal methods

}

 

Is this a good approach?  Should biz rules have this kind of behavior, the reason I went down this road is b/c there are cases when I may(or may not) want a child object.  It depends on the value of SomeId.

If this is not a good approach, can you suggest a better one?

Chris62 replied on Thursday, January 26, 2012

It's those "AffectedProperties" that got me again.  If any needs the answer, something like:

private class ChildCreateRule

{

public ChildCreateRule(PropertyInfo PrimaryProperty, PropertyInfo ChildProperty)

: base(PrimaryProperty)

{

InputProperties.Add(PrimaryProperty);

AffectedProperties.Add(ChildProperty);

}

protected override void Execute(Csla.Rules.RuleContext context)

{

base.Execute(context);

int id = (dynamic)context.InputPropertyValues[PrimaryProperty];

if(id > SomeNumber)

{

ChildClass kid = ChildClass.NewChildClass();

IPropertyInfo childInfo = AffectedProperties[0];

context.AddOutValue(childInfo, kid);

}

}

}

JonnyBee replied on Thursday, January 26, 2012

Hi,

I do not recommend to use a business rule delete/create child objects.

I'd rather look at using authorization rules or overloads of Can<XYZ> to "hide" the child object/property values when they should not be available (readable/editable) and shortcircuit the validation rules when user is not allowed to edit fields.

 

 

richardb replied on Friday, January 27, 2012

I agree with JonnyBee, and that's what we've done in our apps with CanAddBusinessCase, CanDelete_xxxx methods as an example, etc, as we can use these not only to check if user is in correct role, but also look at our custom permissions model and of course execute lookups against our database and/or query other business objects.

Chris62 replied on Friday, January 27, 2012

The logic to determine if a child object gets created isn't tied to authorization, it's more like "if (SomePropertyId == 5) CreateChild".  The basic design is when the parent object is saved to the database, if a property is set to a particular value, then create the child and insert into the db with the parent.  There would be no UI piece or any way for the user to interact with it(this is by design).

If you have access/authorization to the root object, then you have access/authorization to create/save the child object.  

JonnyBee replied on Friday, January 27, 2012

Hi,

Then it seems to me that this is Save-logic (that belongs in the Data Access Layer) and not a business rule in the Business Object.

Chris62 replied on Friday, January 27, 2012

That was my original thought, but then I moved it to a business rule.  I'll be moving it back in the DA layer.

Copyright (c) Marimer LLC