Jeff B
Jeff B

Reputation: 8982

Storing events in a dictionary, and then raising them

I managed to get a dictionary that can store events:

'Terrible .NET events... where's sender and e?!
Public Event ItHappened()
Public Event ItAlmostHappened()

Private mapping As New Dictionary(Of String, System.Delegate) From _
    {{"happened", ItHappenedEvent},
     {"almostHappened", ItAlmostHappenedEvent}}

Great! Now that I have this dictionary, I can convert a stringly-typed event stream into I'm-a-real-boy events! I even figured out how to call them:

 mapping(key).DynamicInvoke()

But alas mapping(key) is null... even after adding a handler for the event. If I update the value in the dictionary to mapping("happened") = ItHappenedEvent after adding an handler, then all is well. Is there a way I accomplish something similar programmatically? Or otherwise store off a string -> event map to translate string input into events at runtime?

Edit:

Real code as requested. This is part of a mechanism to allow us to pass commands to a WinService running on the server. The "do the simplest thing you can possibly do" approach lead us to using files placed on the server as a signaling mechanism.

Public Class CommandChecker
  Implements IDisposable

  Public Event RefreshPlannableStations()

  Private _knownCommmands As New Dictionary(Of String, System.Delegate) From _
    {{"refreshStations", RefreshPlannableStationsEvent}}

  Private WithEvents _fsw As FileSystemWatcher

  Public Sub New(ByVal path As String)
    Me._fsw = New FileSystemWatcher(path, "*.command")
  End Sub

  Private Sub fsw_Created(ByVal sender As Object,
                          ByVal e As FileSystemEventArgs) Handles _fsw.Created
    If Me._knownCommmands.ContainsKey(key) Then
      Me._knownCommmands(key).DynamicInvoke()
      'Delete file to acknowledge command
    EndIf
  End Sub

  'Snipped IDisposable stuff
End Class

Elsewhere, we create this class, and then subscribe to its event.

Me._checker = New CommandChecker()
AddHandler Me._checker.RefreshPlannableStations, AddressOf OnRefreshStations

Upvotes: 1

Views: 394

Answers (1)

default.kramer
default.kramer

Reputation: 6103

It sounds like a layer of indirection will help you here. Instead of mapping the string to the event directly, map the string to an action that will raise the event, like so:

Private mapping As New Dictionary(Of String, Action) From _
    {{"happened", Sub() RaiseEvent ItHappened()},
     {"almostHappened", Sub() RaiseEvent ItAlmostHappened()}}

Upvotes: 3

Related Questions