Sigenes
Sigenes

Reputation: 495

Handle an event outside the current class

I'm writing an application with many features that are events-based rather than explicitly called. I've implemented an Event "notifier" called EventHost that raises certain events of interest, and I'd like for any feature in my application to be able to "subscribe" and respond to events in EventHost that they care about. Below is some pseudocode that demonstrates what I'm after:

Module Globals
    Public WithEvents MyEventHost As EventHost
End Module

Class MyCoolFeature1
    Shared Sub EventXHandler() Handles Globals.EventHost.EventX
        ' Do cool stuff...
    End Sub
End Class

' And likewise for any number of new features.

The problem is, as indicated by the error I'm getting, "Handles clause requires a WithEvents variable defined in the containing type or one of its base types."

I'm familiar with how to use events in this manner, using a WithEvents field in the class itself. However, this requires instantiating the WithEvents field at some point, which can only be done by writing extra code outside of my feature itself, somewhere else in the application. The internal WithEvents field could be instantiated explicitly (by saying something like MyCoolFeature1.EventHost = MyEventHost), or using something like the observer pattern, which requires registering each new feature with the Event Host.

What I'm trying to do is avoid this "registering" step. It's just an extra step that is likely to be forgotten, and seems unnecessary. It seems like it should be possible for an event raiser like EventHost to simply "broadcast" its events, and for event-listeners like MyCoolFeature1 to simply "subscribe" to the event raiser. This way, developers could just create new features and have them handle events in the global EventHost that they care about, and let that be that.

But it seems, due to the "WithEvents variable must be in the same class" limitation, that this may not be possible. It seems like creating features will have to be a two-step process: 1. Code the feature's class and methods, with "Handles" clauses, 2. "Register" the feature somewhere else in my application as a listener to the EventHost.

Is there some way to simply subscribe a method in my class directly to an outside event raiser, without the need for extra outside code to "hook it up" to said event raiser? I'd be happy with some design pattern or technique that uses something other than .NET's stock Events, if necessary.

Upvotes: 0

Views: 82

Answers (1)

jmcilhinney
jmcilhinney

Reputation: 54427

You can't use Handles unless there is a field IN THE SAME TYPE declared WithEvents, which is obviously not an option for an event of a module or Shared event of a class. You have no choice but to use an AddHandler statement. Where you put it is up to you but, in a regular class, you'd probably do it in a parameterless constructor:

Public Module SomeModule

    Public Event SomeEvent As EventHandler

End Module
Public Class SomeClass

    Public Sub New
        AddHandler SomeModule.SomeEvent, AddressOf SomeModule_SomeEvent
    End Sub

    Private Sub SomeModule_SomeEvent(sender As Object, e As EventArgs)
        '...
    End Sub

End Class

Upvotes: 1

Related Questions