Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / July 2007

Tip: Looking for answers? Try searching our database.

Passing events between different classes

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Tom - 16 Jul 2007 20:26 GMT
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
Peter Duniho - 16 Jul 2007 20:50 GMT
> 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
[quoted text clipped - 5 lines]
> 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
Ignacio Machin ( .NET/ C# MVP ) - 16 Jul 2007 21:26 GMT
Hi,

> 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
[quoted text clipped - 5 lines]
> 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?
Tom - 16 Jul 2007 21:39 GMT
On Jul 16, 4:26 pm, "Ignacio Machin \( .NET/ C# MVP \)" <machin TA
laceupsolutions.com> wrote:
> Hi,
>
[quoted text clipped - 15 lines]
>
> 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?
Peter Duniho - 16 Jul 2007 23:36 GMT
> 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
        }
    }
Tom - 17 Jul 2007 19:16 GMT
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 - 26 Jul 2007 21:18 GMT
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
Peter Duniho - 26 Jul 2007 21:22 GMT
> [...] 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
Tom - 26 Jul 2007 21:36 GMT
On Jul 26, 4:22 pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
> > [...] Based on the previous
> > example, show above, it looks like it needs to know about the
[quoted text clipped - 12 lines]
>
> Pete

That seemed to work great.  Thanks Again!!

Tom
Ignacio Machin ( .NET/ C# MVP ) - 17 Jul 2007 15:57 GMT
Hi,

> On Jul 16, 4:26 pm, "Ignacio Machin \( .NET/ C# MVP \)" <machin TA
> laceupsolutions.com> wrote:
[quoted text clipped - 25 lines]
> 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 !!!

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.