Please bear with me as I've only started programming in C# 2 weeks ago
and this is my first contact with OOP.
I ran into a situation where I needed to catch an event in an object
that had no connection or reference to the object that triggered it.
It goes something like this: (not syntactically correct..it's just for
the idea)
main()
{ A a;
C c;
a.Run();
}
class A
{ B b;
C c;
Run()
{ // Trigger the Event here}
} // class
class B
{ C c;
}
class C
{ // Catch and handle the event here
}
Which means that the event would be handled by the 3 instances of C.
>From My research I gathered that I should be using something calledthe "Mediator Pattern".
Unfortunately I could not find a working example of this.
Also, from what I was able to understand, to make it work with this
pattern would require that I derive class C from an abstract
"participan t". Is that right ?
I then kind of gave up on trying to make it work with this pattern
(out of frustration at my failures) and proceeded to try and implement
something that I was a bit more familiar with (from my backgroung with
PCS):
The Publish / Subscribe model (is that also known as a pattern?)
I was pleasantly surprised that it worked.
Here's my working implementation:
All classes use the following:
using System;
using System.Collecti ons.Generic;
using System.Text;
With the class Dispatcher also using:
using System.Collecti ons;
class Program
{
static void Main(string[] args)
{
A a = new A();
C c = new C("C1");
for(int i = 1; i <= 3; i++)
{
a.Run(i);
}
Console.ReadKey ();
}
}
class A
{
B b = new B();
C c = new C("C2");
public void Run(int i)
{
Dispatcher.Publ ish("MyEvent", "Hello #" + i.ToString());
}
}
class B
{
C c = new C("C3");
}
class C
{
private string name;
public C(string name)
{
this.name = name;
Dispatcher.Subs cribe("MyEvent" , OnMyEvent);
}
public void OnMyEvent(objec t appEventParams)
{
string textReceived = (string)appEven tParams;
Console.WriteLi ne(textReceived + " received in " + name);
}
}
public delegate void AppEventHandler (object appEventParams) ;
static class Dispatcher
{
private static Hashtable registry = new Hashtable();
public static void Subscribe(strin g appEvent, AppEventHandler
appEventHandler )
{
Subscription(ap pEvent, appEventHandler , true);
}
public static void Unsubscribe(str ing appEvent,
AppEventHandler appEventHandler )
{
Subscription(ap pEvent, appEventHandler , false);
}
private static void Subscription(st ring appEvent,
AppEventHandler appEventHandler , bool add)
{
ArrayList list;
if (add)
{
if (registry[appEvent] == null)
registry.Add(ap pEvent, new ArrayList());
list = (ArrayList)regi stry[appEvent];
list.Add(appEve ntHandler);
}
else
{
if (registry[appEvent] != null)
{
list = (ArrayList)regi stry[appEvent];
list.Remove(app EventHandler);
}
}
}
public static void Publish(string appEvent, object
appEventParams)
{
ArrayList list;
AppEventHandler appEventHandler ;
if (registry[appEvent] != null)
{
list = (ArrayList)regi stry[appEvent];
for (int i = 0; i < list.Count; i++)
{
appEventHandler = (AppEventHandle r)list[i];
if (appEventHandle r != null)
appEventHandler (appEventParams );
}
}
}
}
The ouput is:
Hello #1 received in C3
Hello #1 received in C2
Hello #1 received in C1
Hello #2 received in C3
Hello #2 received in C2
Hello #2 received in C1
Hello #3 received in C3
Hello #3 received in C2
Hello #3 received in C1
Here are my questions (about time you'll say...sorry about that too
long preambule):
1) Is 'this" somehow a valid implementation of the Mediator pattern
and if not, it is known under another name ? (I hope it's not one of
those anti-pattern)
2) If it's not a valid implementation of the Mediator pattern (or
another "good" pattern), is there any reason why you would advise
"against" this approach. Did I miss an obvious flaw ? Did I do a big
no-no ?
3) Could you "please" (pretty, pretty please) give me a valid
implementation of the Mediator pattern that would give me the exact
same behavior as in my example. (If possible please give me working
code)
4) Any other comments, good of bad, that you think might help me with
this problem.
Thanks a lot in advance.