Passing events between different classes

Discussion in 'Microsoft C# .NET' started by Tom, Jul 16, 2007.

  1. Tom

    Tom Guest

    This is probably a really basic question, but I know someone will be
    able to help me. I have a single object A that contains a hash of
    objects B. Each object B contains its own TCP client object containing
    a connection to a server somewhere.

    There is also a completely separate hash of objects C at the same
    place as Object A. When I get TCP data into the TCP client I need to
    let all of the object C's know about it. I Was wondering if I could
    have all of the C objects register for the B events?

    Tom
     
    Tom, Jul 16, 2007
    #1
    1. Advertisements

  2. Tom

    Peter Duniho Guest

    On Mon, 16 Jul 2007 12:26:13 -0700, Tom <> wrote:

    > This is probably a really basic question, but I know someone will be
    > able to help me. I have a single object A that contains a hash of
    > objects B. Each object B contains its own TCP client object containing
    > a connection to a server somewhere.
    >
    > There is also a completely separate hash of objects C at the same
    > place as Object A. When I get TCP data into the TCP client I need to
    > let all of the object C's know about it. I Was wondering if I could
    > have all of the C objects register for the B events?


    Is object A at all relevant? You didn't mention it with respect to the
    communication between the objects B and objects C, so for the moment I'm
    essentially (mostly) ignoring your first paragraph.

    Anyway, yes...you can have each object C subscribe to an event on each
    object B if you like. Every time an object C is instantiated, it would
    have to subscribe to every object B's event, and every time an object B is
    instantiated, each object C would need some way to know so that each can
    subscribe to the new object B's event.

    You may want to consider a "mediator"-based design, in which there's an
    intermediate class that handles the connections between objects C and
    objects B. Perhaps this is object A, or maybe you will want to make
    another object to do this. You don't provide enough specifics for anyone
    else to suggest which is better, so you'll have to decide that for
    yourself.

    The way the mediator would work is that objects C would all subscribe to a
    single event on the mediator, while the mediator would subscribe to each
    of the objects B event. Then when the mediator receives the event raised
    by any object B, it would forward that event to its own event, which would
    automatically result in each object C receiving the event.

    This way each object C only needs to deal with a single object (the
    mediator) and does not need to concern itself with the instantiation of
    new objects B, while each object B would only have a single object (the
    mediator) subscribed to its own event. Also, it encapsulates the
    management of dealing with instantiations of each object B into a single
    class (a nice way to do that would be to make the object B class aware of
    the mediator, and register itself when it's instantiated, providing a
    method in the mediator that in turn subscribes the mediator to the object
    B event).

    Pete
     
    Peter Duniho, Jul 16, 2007
    #2
    1. Advertisements

  3. Hi,


    "Tom" <> wrote in message
    news:...
    > This is probably a really basic question, but I know someone will be
    > able to help me. I have a single object A that contains a hash of
    > objects B. Each object B contains its own TCP client object containing
    > a connection to a server somewhere.
    >
    > There is also a completely separate hash of objects C at the same
    > place as Object A. When I get TCP data into the TCP client I need to
    > let all of the object C's know about it. I Was wondering if I could
    > have all of the C objects register for the B events?


    You could do so, but then you will have to let each C instance know of every
    B objects.

    A better approach might be if A is the one that subscribe to B's and then A
    will iterate in C's.

    btw, how you are keeping receiving info from all those B's instances?
     
    Ignacio Machin \( .NET/ C# MVP \), Jul 16, 2007
    #3
  4. Tom

    Tom Guest

    On Jul 16, 4:26 pm, "Ignacio Machin \( .NET/ C# MVP \)" <machin TA
    laceupsolutions.com> wrote:
    > Hi,
    >
    > "Tom" <> wrote in message
    >
    > news:...
    >
    > > This is probably a really basic question, but I know someone will be
    > > able to help me. I have a single object A that contains a hash of
    > > objects B. Each object B contains its own TCP client object containing
    > > a connection to a server somewhere.

    >
    > > There is also a completely separate hash of objects C at the same
    > > place as Object A. When I get TCP data into the TCP client I need to
    > > let all of the object C's know about it. I Was wondering if I could
    > > have all of the C objects register for the B events?

    >
    > You could do so, but then you will have to let each C instance know of every
    > B objects.
    >
    > A better approach might be if A is the one that subscribe to B's and then A
    > will iterate in C's.
    >
    > btw, how you are keeping receiving info from all those B's instances?


    I guess I am confused as to the fact that in order to subscribe to an
    event, you have to have an instance of the event generating class
    defined in your class. X must be created in Y for Y to subscribe to X
    events. How would you make a Mediator class without instantiating the
    others classes in it?
     
    Tom, Jul 16, 2007
    #4
  5. Tom

    Peter Duniho Guest

    On Mon, 16 Jul 2007 13:39:19 -0700, Tom <> wrote:

    > I guess I am confused as to the fact that in order to subscribe to an
    > event, you have to have an instance of the event generating class
    > defined in your class. X must be created in Y for Y to subscribe to X
    > events.


    That's not true. Can you explain why it is you think it is? Y need not
    even contain a reference to X, never mind is X required to be created "in"
    or "by" Y.

    The only requirement is that at the point in time that Y subscribes to the
    event, it have a reference to the object on which the event exists. Once
    it's subscribed to the event, it no longer needs the reference to the
    object.

    > How would you make a Mediator class without instantiating the
    > others classes in it?


    However you like. The other classes need not be instantiated within the
    mediator class.

    A fairly common scenario would be to make the Mediator class a singleton..
    This fits with the usual design of there always being just one Mediator,
    and provides a nice, easy way to obtain a reference to the Mediator
    instance (i.e. via a static method that returns the instance).

    But you can put the mediator instance wherever you like, as long as those
    classes that need to us it can get to it.

    As a quick and dirty example (in other words, I have no idea if this will
    actually compile, but hopefully it gets the point across):

    // This class publishes the event that the subscribers are interested
    in
    public class Publisher
    {
    public event EventHandler TheEvent;

    public Publisher()
    {
    // On instantiation, inform the mediator class that this
    instance exists
    Mediator.Instance.Register(this);
    }
    }

    // This class mediates between the instances that publish the event
    and those
    // that subscribe to it
    public class Mediator
    {
    // The mediator needs its own event that the subscribers can
    subscribe to,
    // rather than them subscribing to each Publisher instance's event
    public event EventHandler TheEvent;

    // singleton instance
    private static Mediator _mediator;

    // hide the constructor
    private Mediator()
    {
    }

    // accessor to get the one instance of the class
    public static Mediator Instance
    {
    get
    {
    if (_mediator == null)
    {
    _mediator = new Mediator();
    }

    return _mediator;
    }
    }

    // When the Publisher instance calls this, the Mediator subscribes
    to its event
    public void Register(Publisher publisher)
    {
    publisher.TheEvent += _MyHandler;
    }

    // In the handler for the event, the Mediator then raises the
    event for everyone
    // subscribed to it.
    private void _MyHandler(object sender, EventArgs e)
    {
    EventHandler handler = TheEvent;

    if (handler != null)
    {
    handler(sender, e);
    }
    }
    }

    // This is the class that is actually interested in the event that the
    Publisher exposes
    public class Subscriber
    {
    // Upon instantiation (or wherever you like) the subscriber
    subscribes not to the
    // Publisher's event directly, but to the Mediator's event
    public Subscriber()
    {
    Mediator.Instance.TheEvent += _MyHandler;
    }

    // And of course, you ultimately need a handler that does
    something real. :)
    private void _MyHandler(object sender, EventArgs e)
    {
    // do whatever here
    }
    }
     
    Peter Duniho, Jul 16, 2007
    #5
  6. Hi,

    "Tom" <> wrote in message
    news:...
    > On Jul 16, 4:26 pm, "Ignacio Machin \( .NET/ C# MVP \)" <machin TA
    > laceupsolutions.com> wrote:
    >> Hi,
    >>
    >> "Tom" <> wrote in message
    >>
    >> news:...
    >>
    >> > This is probably a really basic question, but I know someone will be
    >> > able to help me. I have a single object A that contains a hash of
    >> > objects B. Each object B contains its own TCP client object containing
    >> > a connection to a server somewhere.

    >>
    >> > There is also a completely separate hash of objects C at the same
    >> > place as Object A. When I get TCP data into the TCP client I need to
    >> > let all of the object C's know about it. I Was wondering if I could
    >> > have all of the C objects register for the B events?

    >>
    >> You could do so, but then you will have to let each C instance know of
    >> every
    >> B objects.
    >>
    >> A better approach might be if A is the one that subscribe to B's and then
    >> A
    >> will iterate in C's.
    >>
    >> btw, how you are keeping receiving info from all those B's instances?

    >
    > I guess I am confused as to the fact that in order to subscribe to an
    > event, you have to have an instance of the event generating class
    > defined in your class. X must be created in Y for Y to subscribe to X
    > events. How would you make a Mediator class without instantiating the
    > others classes in it?


    Please refer to the classes using the same naming you used before (A,B,C)
    using X and Y now only created confusion.

    A is a single object (from your first post) so it can be safe to think that
    it does exist at everytime. Each tmie a new B instance is created it can get
    a hold of the A instance (a Singleton class?) and can subscribe a member of
    A to the event that B will raise.

    The same can happen with C, each instance can get THE reference to A and
    subscribe to the event that A will fire when an event from B is received. As
    you can see in this implementation B is not aware of C. At the same time you
    can have the instances of B & C created anywhere, not only that but you do
    not need to hold a reference to neither B's nor C's !!!
     
    Ignacio Machin \( .NET/ C# MVP \), Jul 17, 2007
    #6
  7. Tom

    Tom Guest

    Thanks Peter,

    This has really clarified everything for me, I guess I was just used
    to doing things a certain way...

    Thanks again,
    Tom
     
    Tom, Jul 17, 2007
    #7
  8. Tom

    Tom Guest

    I am feeling very frusturated about this right now. The part that is
    frusturating is the:

    // When the Publisher instance calls this, the Mediator
    subscribes
    to its event
    public void Register(Publisher publisher)
    {
    publisher.TheEvent += _MyHandler;
    }


    I have moved my mediator class to the utilites namespace of our
    project. Both classes that need to use the mediator are in different
    namespaces, but both use the utilities namespace. So that is great
    and all until I get to the Register function. Based on the previous
    example, show above, it looks like it needs to know about the
    Publisher class. Is there a way to get around it having to know about
    the publisher class? Since all my classes are USING ProgramUtils;, I
    feel it would be improper to have USING MainProgram; in the utils?

    Tom
     
    Tom, Jul 26, 2007
    #8
  9. Tom

    Peter Duniho Guest

    On Thu, 26 Jul 2007 13:18:05 -0700, Tom <> wrote:

    > [...] Based on the previous
    > example, show above, it looks like it needs to know about the
    > Publisher class. Is there a way to get around it having to know about
    > the publisher class?


    You can do it a couple of ways:

    1) Have a Publisher base class that the actual publisher class
    inherits. The Publisher base class would be declared with the Mediator
    class, while the actual publisher class can be declared anywhere, and the
    Mediator and subscribers need not even know the actual publisher class.

    2) Have a Publisher interface that the actual publisher class
    implements. See above.

    Pete
     
    Peter Duniho, Jul 26, 2007
    #9
  10. Tom

    Tom Guest

    On Jul 26, 4:22 pm, "Peter Duniho" <>
    wrote:
    > On Thu, 26 Jul 2007 13:18:05 -0700, Tom <> wrote:
    > > [...] Based on the previous
    > > example, show above, it looks like it needs to know about the
    > > Publisher class. Is there a way to get around it having to know about
    > > the publisher class?

    >
    > You can do it a couple of ways:
    >
    > 1) Have a Publisher base class that the actual publisher class
    > inherits. The Publisher base class would be declared with the Mediator
    > class, while the actual publisher class can be declared anywhere, and the
    > Mediator and subscribers need not even know the actual publisher class.
    >
    > 2) Have a Publisher interface that the actual publisher class
    > implements. See above.
    >
    > Pete



    That seemed to work great. Thanks Again!!

    Tom
     
    Tom, Jul 26, 2007
    #10
    1. Advertisements

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Daniel
    Replies:
    1
    Views:
    301
    Peter Rilling
    Dec 20, 2004
  2. Guest

    Passing Parameters between form classes - C#

    Guest, Feb 7, 2005, in forum: Microsoft C# .NET
    Replies:
    11
    Views:
    606
    Guest
    Feb 8, 2005
  3. Guest
    Replies:
    11
    Views:
    506
    Jon Skeet [C# MVP]
    Jan 24, 2006
  4. AMP
    Replies:
    7
    Views:
    154
    travisj
    Aug 28, 2006
  5. Daniel
    Replies:
    3
    Views:
    467
    Bruce Wood
    Feb 1, 2007
Loading...

Share This Page