Hi All,
I’m looking for advice on how to handle events in the following scenario:
I have a TcpConnection object which I’ve written to handle creating client/server connections and managing them. It has some events:
- Connecting
- Connected
- ConnectionFailed
- Disconnecting
- Disconnected
Now for an example project, a telnet program. I have a class called TelnetProtocol which uses my TcpConnection object to handle its connection. Ok great, so I subscribe to my TcpConnection events in my telnet protocol and do what I need to. Now I also have TelnetTerminal control for a form that uses a TelnetProtocol object to handles its connection and similarly needs to subscribe to connected, disconnected etc events. Finally I have a form that hosts the TelnetTerminal control and also wants to subscribe to the connected, disconnected etc. events (displays these events in the status bar).
Now my question is this, what is the best way to handle this event “bubbling” I have an event that occurs way down in the TcpConnection and I don’t want to expose the TcpConnection object to the world since the TelnetProtocol object is managing it, and I don’t want to expose the TelnetProtocol object from the TelnetTerminal class and so on.
I tried some solutions out but I don’t think it elegant and I find it hard to believe there isn’t a more sensible method I’m missing. So here goes my first attempt was this:
public class TelnetProtocol { private TcpConnection m_TcpConnection = new TcpConnection(); public event EventHandler<EventArgs> Connected |
I have a public event in my TelnetProtcol class called Connected that just maps directly to the TcpConnection object below. Now the big problem with this is that when the event subscriber receives the event the source object is the TcpConnection and not the TelnetProtocol as expected. Not only does this allow access to the TcpConnection when I wanted to hide it, it also break expected behaviour, the source should be the TelnetProtocol.
Ok so with that being a bad idea I tried this:
public class TelnetProtocol public event EventHandler<EventArgs> Connected; private void OnConnected() public TelnetProtocol() |
This works great, I basically pass the event on when I receive it from the TcpConnection, but at what overhead cost Plus the fact that I have to write the event firing functions for each event I want to expose (Connect, Disconnect etc.) this becomes more tedious as the exact same functionality has to also be implemented in the TelnetTerminal control which will pass off the TelnetProtocol events as its own!
I haven’t thought of any other way to do this properly and I can’t help but think I’m missing something. If anyone has a better solution to this or any suggestions on alternative methods I’d really like to hear it. What do other developers do to expose events that are hidden down a hierarchy of classes
I hope this makes sense, many thanks in advance for replies,
Chris

Propagating events up an object chain
Jaswant Singh Rana
Thanks Karthik, that's an interesting idea I've never encountered the observer design pattern. However, if the TcpChangeBroadcaster is a singleton, how would you handle having multiple TcpConnections, for example, my telnet application has a tabbed interface so you can connect to more than 1 telnet session at once.
Would you just expose an IBroadcaster object from the TelnetSession and TelnetTerminal which is the underlying TcpConnection How is this different from defining an interface that contains events which the TcpConnection exposes e.g.
public delegate void BroadcastEventHandler();
public interface IBroadcaster
{
event BroadcastEventHandler Connected;
event BroadcastEventHandler Disconnected
}
public class TcpConnection: IBroadcaster
{
public event BroadcastEventHandler Connected;
public event BroadcastEventHandler Disconnected;
}
public class TelnetProtocol
{
private TcpConnection m_TcpConnection = new TcpConnection();
public IBroadcaster BroadcastEvents { get { return m_TcpConnection; } }
}
although, having just written that code example I think I understand how this meets my requirements. Have I understood you correctly or am I missing the point of the observer pattern Is it right to use events or should it be as you described, having two interfaces for IReceiver and IBroadcaster I suppose it is still possible to access the TcpConnection object by casting the IBroadcaster object, so it is probably beneficial to use a helper object to handle the events.
Thanks,
Chris
June Shi
Thanks Karthik, I understand the concepts now it's definatly given me something to think about and a new way of looking at events and notifications.
Chris
Ranjay
The idea behind my design was to delegate the propogation of events to a third class who would be some kind of a mediator.This is the only fellow who knows about the interested parties.So,whenever a connection is established,the TcpConnection would notify the singleton TcpChangeBroadcaster class and forgets about everything.
Now,the TcpChangeBroadcaster has received a notification,he just sends out information to the interested parties,asking them to update themselves.The TcpConnection has now successfully notified all classes through the TcpChangeBroadcaster without even knowing as to whom it notified,because thats the job of the TcpChangeBroadcaster.
Coming to your point on why it should be a singleton,we want interested parties to register interest only once and be done with it.The TcpChangeBroadCaster will then become a single point of contact for both the connection object and the observers.
After the long-winding theory,now for the solution of your problem.You may have multiple connections but you have only one TcpChangeBroadcaster object,right So how can you tell which connection got connected.You can change the signature of your ReceiveEvent method to pass the connection object itself and you can choose to pass relevant portions of the connection object (maybe a connection string or something , which may be a property of the connection object)to the underlying observers.
Did you understand what I said or was it all non-sense
Kedar
This is nowhere as neat as Karthiks but you could change your event parameters to include the event type.
So your top-level object intercepts the events, and calls an internal routine passing the event type as a parameter. It then triggers the event Universal_Event_Handler on all its 'children' .Each child decides if it is going to:
1) handle it
2) Handle it and pass it on
3) Just pass it on
The you only need the same Universal_Event_Handler in each 'level' with a case statement. Cut and paste does the rest.
Paul
Ink Master
You can use the observer design pattern to decouple your the classes that are interested to receive notifications from the class that raises the event
You can have two interfaces such as-
public
interface IBroadcaster{
void Add(IReceiver observer); void Remove(IReceiver observer); void BroadcastChanges();}
public class IReceiver{
void ReceiveNotification();}
Move all notifications that the TcpConnection raises,by making a single class receive the notifications-
public
class TcpChangeBroadcaster : IBroadcaster{
//TBD-Make this is a singleton class private ArrayList list = new ArrayList();#region
IBroadcaster Members public void Add(IReceiver receiver){
list.Add(receiver);
}
public void Remove(IReceiver receiver){
list.Remove(receiver);
//TBD-check if it exists}
public void BroadcastChanges(){
foreach (IReceiver receiver in list) { receiver.ReceiveNotification(); }}
/// <summary> /// This method is called whenever the TcpConnection object raises an event /// This inturn notifies all receivers.Modify this method to suit your scenario /// to tell which event was fired /// </summary> public void ReceiveEvent(){
BroadcastChanges();
}
#endregion
}
Please note that this is a rough design and you may need to enhance it as per your requirements.This also ensures that any class can receive notifications,without the need to explicitly subscribe for the event in the TcpConnection class.