[Webinar] Streamline your web hosting managementRegister Today

x
?
Solved

How to subscribe to parent events from a newly added child object in the business object hierarchy

Posted on 2008-02-11
4
Medium Priority
?
484 Views
Last Modified: 2010-04-15
I'll use the old Invoice example.  Let's say I have a business object hierarchy that looks like this:
Invoice
----- Orders
----------LineItems

Let's say there is a property on the invoice called "Customer".  If I change the customer name, I would like the LineItem object to know about it.  I am unsure how to wire this up to autowire when a LineItem is added to an order.

I guess in the Invoice class I need:

public delegate void CustomerChangedHandler(object sender, CustomerChangedEventArgs e);
public event CustomerChangedHandler CustomerChanged;

public string Customer
{
     get { return _customer; }
     set
     {
                _customer = value;
                OnCustomerChanged();
      }
}

Then in the LineItem class I would need the signature, like:
public void CustomerChanged(object sender, CustomerChangedEventArgs e)
 {
     Debug.Writeline("notified.");
}

The implementation of hte business object looks something like this:

private Invoice _invoice.
.
.
.
LineItem lineItem = new LineItem();
int index = _invoice.Orders[2].LineItems.Add(lineItem);

CustomerChangedHandler  customerHandler = new CustomerChangedHandler(_invoice.Orders[2].LineItems[index].CustomerChanged);

_invoice.CustomerChanged += customerHandler;

This seems to work.  However, this seems incorrect because this eventing wireup is outside of the business object.  How can I wire this up from within the business object when a LineItem is added to the LineItems list?  The challenge here is that it seems I need a reference to Invoice object from this child object.  Either that or some event that would fire within the Invoice object would allow me to add an event subscription for this object.



0
Comment
Question by:dentyne
  • 2
  • 2
4 Comments
 
LVL 96

Expert Comment

by:Bob Learned
ID: 20870935
I need to ask why do you think that you need to do this?

Bob
0
 
LVL 1

Author Comment

by:dentyne
ID: 20872439
Well I wanted to have a true business object.  So when someone uses it, if they change some Master data (a subclass of my object one level deep), some other objects n-levels deep in that hierarchy need to recalculate based on this value.  

I didn't want to have to depend on the having to register the events outside the business object because the logic wouldn't be encapsulated anymore.

There are several situations in my obejct in which I'd need this.  For instance, I have a "Products" collection that that some properties.  When a property changes on this collection some things need to recalculate in the individual products in the collection.  There are other situations in which communication is necessary between different levels of business objects.
0
 
LVL 96

Expert Comment

by:Bob Learned
ID: 20874642
I have heard of business objects encapsulating data, but not events.  I am willing to learn new things.  Generally, I prefer to have a business object be a state object, and the events to happen externally to that.  What you are discovering about how to add events at the business object level might probably give you a hint as to why you wouldn't want to do it that way.  Sometimes, you can come up with an idea, and make it work, and then you're the only that understands it.

bob
0
 
LVL 1

Accepted Solution

by:
dentyne earned 0 total points
ID: 20875175
Thanks Bob.

This morning I came up with the idea of enforcing a business hierarchy through constructors. Each "child" object then implements a IHierarchy interface (see code snippet).  Could you look at the code and let me know if it makes sense?

I guess I am initially surprised at how little there is on business object hierarchy event encapsulation.  To me (I'm not an expert), the business object hierarchy is the key to the application and they need to talk to each other. I figured the inner communication needed between business objects are like "business rules".

In my dummy example below, if someone changes some "Calculation Method" on the Invoice, then each order for that invoice needs to be recalculated.  (Bad example, but It's too complex to explain my business need).

So using the Invoice example above, it would be:

public class Invoice
{
     private OrderList _orderList;
     private string _calcType;
     //Define the delegate and event to fire when calculation type changes.
     public delegate void CalcTypeChangedHandler(object sender, InvoiceChangedEventArgs e);
     public event CalcTypeChangedHandler CalcTypeChanged;
     
      public Invoice()
      {
            _orderList = new OrderList(this);
      }
     protected void OnCalcTypeChanged()
     {
            if(CalcTypeChanged != null)
                CalcTypeChanged(this,new CalcTypeChangedEventArgs(this._calcType));
        }
     public string CalculationType
     {
          get{ return this._calcType;}
          set
          {
               this._calcType = value;
               OnCalcTypeChanged();
          }
     }
}

Then, in OrderList:

public OrderList : CollectionBase, IBindingList, IHierarchy
{
     private Invoice _parent;

     public OrderList() {}
     public OrderList(Invoice parent)
     {
          _parent = parent;
     }
     public int Add(Order value)
     {
            //Set the parent of the order then wire up the needed events
            value.Parent = this;
            wireUpOrder(value);
            return List.Add(value);
      }
     
      private wireUpOrder(Order order)
      {
            IHierarchy parent = (IHierarchy)this.Parent;
            while (parent != null)
            {
                if (parent.GetType() != typeof(Invoice))
                {
                    parent = (IHierarchy)parent.Parent;
                }
                else
                {
                    //We're at the invoice level.  Wire this order up to listen to it's calctypechanged event
                    Invoice invoice = (Invoice)parent;
                    invoice.CalcTypeChanged += new Invoice.CalcTypeChangedHandler        
                                      (order.CalcTypeChanged);
                }
            }
      }
     #region IHierarchy members
      public object Parent
      {
           get { return this._parent; }
           set { this._parent = (Invoice) value; }
      }
     #endregion
}

Then in the Order:

public class Order : IHierarchy
{
     public void CalcTypeChanged(object sender, InvoiceChangedArgs e)
     {
             Debug.WriteLine("Order is notified of invoice calculation change. Commence recalcs");
     }

     #region IHierarchy members
      public object Parent
      {
           get { return this._parent; }
           set { this._parent = (Invoice) value; }
      }
     #endregion

}

I created the objects and tested their Parent properties and they are all correctly intact.  But I haven't tested the event wiring yet.

I apologize in advance if the code above is incorrect.  I just typed it out.  I have a conversion in my head that translates my real business object  into this Invoice/Order/Item example.
0

Featured Post

Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article describes a simple method to resize a control at runtime.  It includes ready-to-use source code and a complete sample demonstration application.  We'll also talk about C# Extension Methods. Introduction In one of my applications…
Summary: Persistence is the capability of an application to store the state of objects and recover it when necessary. This article compares the two common types of serialization in aspects of data access, readability, and runtime cost. A ready-to…
As many of you are aware about Scanpst.exe utility which is owned by Microsoft itself to repair inaccessible or damaged PST files, but the question is do you really think Scanpst.exe is capable to repair all sorts of PST related corruption issues?
Free Data Recovery software is an advanced solution from Kernel Tools to recover data and files such as documents, emails, database, media and pictures, etc. It supports recovery from physical & logical drive after a hard disk crash, accidental/inte…
Suggested Courses
Course of the Month10 days, 7 hours left to enroll

612 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question