During my research on CSLA, I found a problem which confused me these days:
A business Object has a member field named _parent that is a reference to the Collection Object which contain it. But, during many business applications, the validation rules and authorization rules of a child object usually utilize the information of its root object rather than the collection object which containing it.
I will take ProjectTracker as an example. I assumed that there is a validation rule such as :"if days between started date and Ended date is no more than 10 days, then the total number of resource needed should be less than 4 ". When this rule is established in the ProjectResource class, started date and ended date should be achieved from the Root Object(that's Project) while the total number can be achieved from the collection object, but it seemed that ProjectResource object doesn’t having the referrence to a Project object.
To solve this problem, I do the following work.
1.Firstly declare a private filed in the ProjectResource class and establish corresponding attribute and set method
[NotUndoable()]
[NonSerialized()]
private Project _parent;
public PriceSuite Parent
{
get { return _parent; }
}
internal void SetParent(Project project)
{
_parent = project;
}
2.Secondly override OnDeserialized in the Project calsss,
protected override void OnDeserialized(StreamingContext context)
{
this._resources.SetParent(this);
}
3.add this sencentence in method DataPortal_Create of Projectclass to cope with locally creating project object
protected override void DataPortal_Create(object criteria)
{
_id = Guid.NewGuid();
_started.Date = DateTime.Today;
this._resources.(this);
ValidationRules.CheckRules();
}
Then in every ProjectResource object, the reference of Project object can be achieved through ((ProjectResource)this.Parent).Parent.
I don't know whether it is a satisfied solution. Because I think ProjectResource class doesn't hold the reference of its root object in CSLA.NET architecture. Does it mean that these business rules should be implemented in the Project class. If it is,how to appropriate to implemente it?
thks
One of the
basic OOP principles to keep in mind is program to an interface and not an
implementation. A child should not have
a reference to its concrete parent. A
child should know as little about its parent as possible. It is not a good idea for the child to have a
reference to its parent because it becomes tightly-coupled with its parent. This creates a rigid design and does not make
your child reusable. The most common way
to solve your problem is to abstract out what your child needs into an
interface or abstract class. The parent
should implement this interface and the child should only reference the parent
through this interface.
malloc1024:One of the basic OOP principles to keep in mind is program to an interface and not an implementation. A child should not have a reference to its concrete parent. A child should know as little about its parent as possible. It is not a good idea for the child to have a reference to its parent because it becomes tightly-coupled with its parent. This creates a rigid design and does not make your child reusable. The most common way to solve your problem is to abstract out what your child needs into an interface or abstract class. The parent should implement this interface and the child should only reference the parent through this interface.
validation rules like "if days between started date and Ended date is no more than 10 days, then the total number of resource needed should be less than 4 " contains information from the root object Prjoect and the child Object ProjectResource,at last, i implement this in the Project Class like this:
protected override void OnDeserialized(System.Runtime.Serialization.StreamingContext context)
{
_resources.ListChanged += new System.ComponentModel.ListChangedEventHandler(Resources_ListChanged);
}
and if the DataPortal_Create Method is RunLocal(),add the sentence before ValidationRules.CheckRules();
[RunLocal()]
protected override void DataPortal_Create(object criteria)
{
_id = Guid.NewGuid();
_started.Date = DateTime.Today;
_resources.ListChanged += new System.ComponentModel.ListChangedEventHandler(Resources_ListChanged);
ValidationRules.CheckRules();
}
then we could do complex rule validation in the method Resources_ListChanged
void Resources_ListChanged(object sender, System.ComponentModel.ListChangedEventArgs e)
{
//do complex validation things;
}
Copyright (c) Marimer LLC