Perhaps this is a dumb question, but I've tried Google and the newsgroups, and can't figure out a satisfactory answer yet.
I'd like to make publish/subscribe scenario where the publishing object is a couple of layers removed from the subscriber. The publisher fires an event and doesn't know who (if anyone) is listening. The subscriber, on the other hand, wants the information, but doesn't want to know who published it (to fully decouple the two from one another).
Publisher -->> Fires Event
ObjectList (contains subscriber objects) --> SubscriberObject (receives event).
Do I need to keep the event as a public static member of the Publisher class or is there a way that I can pass it down to subscriber. I can't pass an event as a parameter. Am I looking at this the wrong way?
Thanks!
George
Hi George,
I faced more or less the same problem this week, only more so, since I
needed several "publishers" to fire the exact same event, the
"subscriber" not caring where the event comes from. I came up with the
following workaround, which does it for me.
I have a separate claas library, called "KioskEvents" (Kiosk being the
general name I use for this software project). This library contains
all events, EventArgs-derived classes and event delegate declarations
used throughout the solution. For each event, there is a public method
that actually fires the event. This method can be called from anywhere
in the solution (provided the component references the KioskEvents
class library).
Here is the meat of the events class library, providing for just one
event. This event passes a string to the subscriber. Note that in this
setup, the subscriber can still tell who the original publisher is:
it's right there in the "sender" parameter.
I have tried to make this code readable in a newsreader by using
spaces instead of tabs; use a fixed font such as courier to read this
namespace kiosk
{
////////////////////////////////
// Event Arguments
////////////////////////////////
public class CEventArgsString : EventArgs
{
public string strData ;
}
///////////////////////////////
// Event Delegates
//////////////////////////////
public delegate void EventHandlerString
( Object sender, CEventArgsString eString );
public class CKioskEvents
{
////////////////////////////
// Events
////////////////////////////
public static event EventHandlerString eventNewStation;
////////////////////////////
// Event-raising methods
////////////////////////////
public static void RaiseEventNewStation(
object sender, string strStation )
{
if( eventNewStation != null )
{
CEventArgsString eString = new CEventArgsString( );
eString.strData = strStation ;
eventNewStation( sender, eString );
}
}
} // CKioskEvents
} // kiosk namespace
So, to raise the event, the publisher would call
CKioskEvents.RaiseEventNewStation( this, strStationName );
To receive the event, the subscriber would have something like
CKioskEvents.eventNewStation +=
new EventHandlerString( OnNewStation );
and of course a handler method called OnNewStation:
void OnNewStation( object sender, CEventArgsString e )
{
string strSender = sender.ToString( );
string strStation = e.strData ;
}
Hope this helps / makes sense !
Jan Roelof