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
}
}