Parent Child Interface Implementation

Parent Child Interface Implementation

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


sgraham posted on Friday, February 15, 2008

I submitted this as part of another post thread but I'm thinking maybe I should start my own post thread since I didn't get any feedback/help.  Please help!

----------------------------------------------------------------------------------------------

I am trying to do something that seems very similar to this.  I am trying to set child authorization (overriding CanWriteProperty) based on parent properties (status). 

Here is basic class diagram of my app.

Use case one - editing a promotion event

Promotional Event (Business Base - Parent)

      PromoList (Read-Only Collection)

            PromoInfo (Read-Only Child)

      PriceList (Business List - Child)

            Price (Business Base - Child)

Use case two - editing a promotion

Promo (Business Base - Parent)

      PromoProducts (Business List - Child)

            PromoProduct (Business Base - Child)

Once my Promotional Event is in submitted or approved status (property of object), I want to set the CanWriteProperty to false for the event and ALL children.  How do I implement the interface on the Promotional Event and Price List objects?  And, how do I make the Price object see the status?

Further, how do I make the Promo object (from the other use case - but still only exists in the context of a promotional event) see the status and set the CanWriteProperty for itself and it's own children?  Is that even possible?

I understand this is also similar to work flow.  And, conceptually I understand the theory behind implementing an interface on the parent and the collection and calling a method in the child to use that interface.  However, I don't understand how to actually do the code for this.  Can somebody please provide a sample of some kind?

Thanks in advance for any help!

SomeGuy replied on Friday, February 15, 2008

You could have an internal property on the Child objects that the parent can set when it's status changes.

E

 

sgraham replied on Friday, February 15, 2008

I realize that.  But, I am trying to do proper OO modeling and loose coupling.  I am trying not to pass data from object to object when it seems like it can be interfaced.  Am I missing something?

ajj3085 replied on Friday, February 15, 2008

Well, there comes a point IMO when you do need to have some coupling.  I think its ok that a set of objects that are to work together to fulfill a use case can be coupled to some extend.  So while you could make things more loosely coupled, I think you're just making it more complex than it needs to be.  As long as the objects aren't expecting a certain implementation, I don't see anything wrong with collaborating to perform a task.

Of course, that's just my opinion.. Smile [:)]

sgraham replied on Friday, February 15, 2008

I actually took that approach of passing the event data to the children (collections and objects) and there are alot of children so it got pretty interesting and I'm still not sure I have it right.  So, instead, I was hoping all the children could just "ask" the parent it's status to determine there editability.  The following comments from Rocky on another post are what I am considering implementing.  I just don't understand the specific code implementation.

"I would define an interface that the parent and collection implement, which contains a method the child can call to ask whether the order has been invoiced.

The implementation in the collection would delegate to the root parent, which can answer the question. This does require that your Order object provide the collection with a parent reference upon creation - but that can be easily handled through the collection's Friend/internal factory method.

The end result though, is that the interface provides relative loose coupling, and the child only knows about its immediate parent (the collection), which it already knows about anyway (due to IEditableObject). Note the protected Parent property that already exists for this purpose."

Either way, I can be flexible.  I just thought that the interface approach might be considerably simpler.  But, since I'm fairly new to OO and especially interfaces, I have no idea how easy or hard it will be and how to actually implement it.

Thoughts?

trives replied on Friday, February 15, 2008

You can try something like this:

public interface IEventStatus
{
    string EventStatus{ get; };
}

In PromotionalEvent, the implementation would be:

public class PromotionalEvent : BusinessBase, IEventStatus
{
    private string _status;
    public string EventStatus
    {
        return _status;
    }
}

In PriceList,

public class PriceList : BusinessListBase, IEventStatus
{
     public string EventStatus
    {
        return ((IEventStatus)this.Parent).EventStatus;
    }
}

In Price,

protected override bool CanWriteProperty(string propertyName)
{
    if (((IEventStatus)this.Parent).EventStatus == "submitted")
    {
        return false;
    }
    return base.CanWriteProperty(propertyName);
}

Does this help?

Tim

sgraham replied on Friday, February 15, 2008

Thank you!  That is a GREAT start!

Now, a few questions from that.

1)  I need to do something to "expose" the parent to the children so that I can use this.Parent, correct?

2)  How would I go about using that interface for the Promo object (which in use case two is a parent - but still needs to follow the rules of it's "database" parent, the Promotional Event)?

Thanks again!

trives replied on Friday, February 15, 2008

1) If you use the managed fields in the 3.5 beta, the parent property is set automatically for you.  If you're not using the 3.5 beta, then I think CSLA still sets the Parent property in the Price objects.  I think you'll need to set the parent in PriceList programmatically.  When you fetch the PriceList collection in PromotionalEvent, you can do something like:

((IEditableCollection)priceList).SetParent(this);

2) Can you load the promotional event status when you fetch the Promo object, or is the status not persisted to the database yet?  My guess is that it's not, or you wouldn't be asking this question.  If it's a question of passing a value from one object to another where there is no reference between the two, then you might consider using the dictionary exposed by ApplicationContext.LocalContext.  That may, however, be inappropriate depending on the circumstances.

stefan replied on Saturday, February 16, 2008


When you fetch the PriceList collection in PromotionalEvent, you can do something like:

((IEditableCollection)priceList).SetParent(this);

And besides that, you will need an override of OnDeserialized in PromotionalEvent

calling ((IEditableCollection)priceList).SetParent(this); as well.

Otherwise you won't get the desired behaviour after calling a DataPotal.XYZ method.


Stefan

sgraham replied on Monday, February 18, 2008

The status is persisted in the database but I was trying to get the value from memory using interfaces (if that's even possible).

What is the dictionary that you refer to?  Why would it be inappropriate?

Copyright (c) Marimer LLC