Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Delegates and events

Delegates and events

Scheduled Pinned Locked Moved C#
sysadminhelpquestion
7 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    mirano
    wrote on last edited by
    #1

    Hello everybody. I have a class A that publishes an event, and is using a delegate to allow other objects to subscribe to it. After raising the event, class A is sending some information wrapped up in the custom class deriving from EventArgs. When the event fires, the class is then going through the list of subscribers using the GetInvocationList() and is getting the response from the subscribers. So far so good. The problem is when trying to subscribe to the event from a class B that has no reference to class A. It would be easy enough to add a reference to it and to just subscribe to the event, however we do not want to make the server code to reference the client classes. Is there a way to do this differently? If not, that what about adding an intermediary object that can receive and pass on the events raised in class A on the client side, so that class B on the server needs only to reference one object* But if there's a better way then I would really appreciate some directions. Thanks a lot. Sarajevo, Bosnia -- modified at 15:21 Wednesday 23rd November, 2005

    L 1 Reply Last reply
    0
    • M mirano

      Hello everybody. I have a class A that publishes an event, and is using a delegate to allow other objects to subscribe to it. After raising the event, class A is sending some information wrapped up in the custom class deriving from EventArgs. When the event fires, the class is then going through the list of subscribers using the GetInvocationList() and is getting the response from the subscribers. So far so good. The problem is when trying to subscribe to the event from a class B that has no reference to class A. It would be easy enough to add a reference to it and to just subscribe to the event, however we do not want to make the server code to reference the client classes. Is there a way to do this differently? If not, that what about adding an intermediary object that can receive and pass on the events raised in class A on the client side, so that class B on the server needs only to reference one object* But if there's a better way then I would really appreciate some directions. Thanks a lot. Sarajevo, Bosnia -- modified at 15:21 Wednesday 23rd November, 2005

      L Offline
      L Offline
      Leslie Sanford
      wrote on last edited by
      #2

      mirano wrote:

      The problem is when trying to subscribe to the event from a class B that has no reference to class A. It would be easy enough to add a reference to it and to just subscribe to the event, however we do not want to make the server code to reference the client classes.

      You could make the event handler in Class B public and have a mediator class attach it to the event in Class A. Or have an interface represent only the event that's in Class A that Class B needs to subscribe to. Hopefully, the event represents something easily identifiable so that it's easy to name. Have Class A implement this interface. Pass an instance of Class A to Class B as a reference to the interface, not Class A. This way, Class B only knows about the interface. This decouples Class B from Class A.

      mirano wrote:

      If not, that what about adding an intermediary object that can receive and pass on the events raised in class A on the client side, so that class B on the server needs only to reference one object*

      I would go the interface route first. The interface is in essence doing the job that your intermediary object is doing, only basically for free. -- modified at 17:47 Wednesday 23rd November, 2005

      M 1 Reply Last reply
      0
      • L Leslie Sanford

        mirano wrote:

        The problem is when trying to subscribe to the event from a class B that has no reference to class A. It would be easy enough to add a reference to it and to just subscribe to the event, however we do not want to make the server code to reference the client classes.

        You could make the event handler in Class B public and have a mediator class attach it to the event in Class A. Or have an interface represent only the event that's in Class A that Class B needs to subscribe to. Hopefully, the event represents something easily identifiable so that it's easy to name. Have Class A implement this interface. Pass an instance of Class A to Class B as a reference to the interface, not Class A. This way, Class B only knows about the interface. This decouples Class B from Class A.

        mirano wrote:

        If not, that what about adding an intermediary object that can receive and pass on the events raised in class A on the client side, so that class B on the server needs only to reference one object*

        I would go the interface route first. The interface is in essence doing the job that your intermediary object is doing, only basically for free. -- modified at 17:47 Wednesday 23rd November, 2005

        M Offline
        M Offline
        mirano
        wrote on last edited by
        #3

        Thank you for your help, Leslie. I will give it a try today. The solution seems reasonable and I was thinking about the interface when I meant intermediary object, just everything is kinda upside down - the server is to subscribe to the event that the clients would raise. The solution with the interface is a common one, but still I wanted to see is there some other pattern that we should use when going with a delegates, event though I could not remember seeing any such implementation. The easiest way is to add a reference to the server, but doing that and in a short time the server implementation gets bloated with too many assemblies. Thanks again. Sarajevo, Bosnia

        L 1 Reply Last reply
        0
        • M mirano

          Thank you for your help, Leslie. I will give it a try today. The solution seems reasonable and I was thinking about the interface when I meant intermediary object, just everything is kinda upside down - the server is to subscribe to the event that the clients would raise. The solution with the interface is a common one, but still I wanted to see is there some other pattern that we should use when going with a delegates, event though I could not remember seeing any such implementation. The easiest way is to add a reference to the server, but doing that and in a short time the server implementation gets bloated with too many assemblies. Thanks again. Sarajevo, Bosnia

          L Offline
          L Offline
          Leslie Sanford
          wrote on last edited by
          #4

          mirano wrote:

          The easiest way is to add a reference to the server, but doing that and in a short time the server implementation gets bloated with too many assemblies.

          I can understand that. If you do try the interface approach, you may want to put it in the server library/assembly. I'm assuming you have a server assembly and various client assemblies that use the server. In this situation, it's understandable that you wouldn't want the server referencing the clients to avoid assembly bloat, but also to avoid a circular dependency as well. You could put a IClient interface (or whatever name seems appropriate to you) in the server library. It would represent the basic functionality the server needs to interact with its clients regardless of where or who they are. In this interface would be the event you described earlier. Client libraries would implement this interface and could register themselves with the server; something like a server.Connect(IClient client) method in which the server subscribes to the event in the IClient interface. Alot of what I've described above is based on some assumptions that may not be true for your situation. At any rate, if it's helpful at all, cool. Just my 2 cents. :)

          M 1 Reply Last reply
          0
          • L Leslie Sanford

            mirano wrote:

            The easiest way is to add a reference to the server, but doing that and in a short time the server implementation gets bloated with too many assemblies.

            I can understand that. If you do try the interface approach, you may want to put it in the server library/assembly. I'm assuming you have a server assembly and various client assemblies that use the server. In this situation, it's understandable that you wouldn't want the server referencing the clients to avoid assembly bloat, but also to avoid a circular dependency as well. You could put a IClient interface (or whatever name seems appropriate to you) in the server library. It would represent the basic functionality the server needs to interact with its clients regardless of where or who they are. In this interface would be the event you described earlier. Client libraries would implement this interface and could register themselves with the server; something like a server.Connect(IClient client) method in which the server subscribes to the event in the IClient interface. Alot of what I've described above is based on some assumptions that may not be true for your situation. At any rate, if it's helpful at all, cool. Just my 2 cents. :)

            M Offline
            M Offline
            mirano
            wrote on last edited by
            #5

            Could not get it to work. Here's the problem: Class A implements the interface IClient that is on the server, everything's fine. When the method Foo of the class A is executed, the event is raised, passing some data class as a reference. Now, in order to subscribe to the event from the server, I need to do something like this: Foo f = new Foo(); IClient icl = f as IClient(); and then: icl.SomeEvent += new ... bla, bla... but I DO NOT HAVE a reference to class A, method Foo, which is the whole point from the very beginning. Is there another way to subscribe to the event that is wrapped in the interface without having to know the class that's implementing it on the client side? Thanks. Sarajevo, Bosnia

            L 1 Reply Last reply
            0
            • M mirano

              Could not get it to work. Here's the problem: Class A implements the interface IClient that is on the server, everything's fine. When the method Foo of the class A is executed, the event is raised, passing some data class as a reference. Now, in order to subscribe to the event from the server, I need to do something like this: Foo f = new Foo(); IClient icl = f as IClient(); and then: icl.SomeEvent += new ... bla, bla... but I DO NOT HAVE a reference to class A, method Foo, which is the whole point from the very beginning. Is there another way to subscribe to the event that is wrapped in the interface without having to know the class that's implementing it on the client side? Thanks. Sarajevo, Bosnia

              L Offline
              L Offline
              Leslie Sanford
              wrote on last edited by
              #6

              You can have a reference to Class A on the server side without knowing its type as long as it implements an interface the server knows about and the reference is passed as a reference to that interface type. Let's look at a bit of code so that what I wrote above is more concrete. In the server library, you have the IClient interface:

              public interface IClient
              {
              event EventHandler ClientChanged;
              }

              Also, we have the Server class:

              public class Server
              {
              public void Connect(IClient client)
              {
              client.ClientChanged += new EventHandler(HandleClientChangedEvent);
              }

              public void Disconnect(IClient client)
              {
                  client.ClientChanged -= new EventHandler(HandleClientChangedEvent);
              }
              
              private void HandleClientChangedEvent(object sender, EventArgs e)
              {
                  // Do something here in response to the client's event.
              }
              

              }

              Now, the Server can attach and detach itself to the client's event without having to know its type. All it knows is that the client implements the IClient interface. Make sense? On the client side, we do have to know about the server, but the dependency is one-side, i.e. not circular, so we're ok:

              public class SomeClient
              {
              public SomeClient(Server s)
              {
              s.Connect(this);
              }

              // ...
              

              }

              -- modified at 13:12 Saturday 26th November, 2005

              M 1 Reply Last reply
              0
              • L Leslie Sanford

                You can have a reference to Class A on the server side without knowing its type as long as it implements an interface the server knows about and the reference is passed as a reference to that interface type. Let's look at a bit of code so that what I wrote above is more concrete. In the server library, you have the IClient interface:

                public interface IClient
                {
                event EventHandler ClientChanged;
                }

                Also, we have the Server class:

                public class Server
                {
                public void Connect(IClient client)
                {
                client.ClientChanged += new EventHandler(HandleClientChangedEvent);
                }

                public void Disconnect(IClient client)
                {
                    client.ClientChanged -= new EventHandler(HandleClientChangedEvent);
                }
                
                private void HandleClientChangedEvent(object sender, EventArgs e)
                {
                    // Do something here in response to the client's event.
                }
                

                }

                Now, the Server can attach and detach itself to the client's event without having to know its type. All it knows is that the client implements the IClient interface. Make sense? On the client side, we do have to know about the server, but the dependency is one-side, i.e. not circular, so we're ok:

                public class SomeClient
                {
                public SomeClient(Server s)
                {
                s.Connect(this);
                }

                // ...
                

                }

                -- modified at 13:12 Saturday 26th November, 2005

                M Offline
                M Offline
                mirano
                wrote on last edited by
                #7

                Yes, you are right. It works. It was just not that obvious how to get the client throught the interface in order to subscribe to the event. Thanks. Sarajevo, Bosnia

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups