Dave ت Maher Dave ت Maher - 1 year ago 52
Vb.net Question

VB.NET Handle event from one class in another without them knowing eachother...?

I have an application.

Module1 - Main application

DataAccessMananger - Class in main application to handle data

Configuration - Class in a different project (common dll) that handles configuration settings.

The problem / Question. How can the Configuration class handle a data changed event in the DataAccessMananger without it knowing what a DataAccessManager is since they are in different classes?

The only way I can think of making it work is to have Module 1 handle the event from the DataAccessMananger and have it call a method in the Configuration class, however I dont like this, I would rather Configuration be able to handle its own data updates...

Clear as mud? Any ideas? VB.NET 4.5, and I know a bit about delegates, but not sure how I could use them here, they must be the answer some how...

Ideally, I would like to be able to pass an "Event" to the config class from the DAM class using the module...

Answer Source

The best way I can think of would be to add an interface in the configuration class (common.dll) that would be implemented by the DataAccessMananger. I assume the mainmodule is aware of both the DataAccessMananger and the Configuration, right ? If so, the following might be a solution.

  1. Add an interface to common.dll for the Configuration class to use (not implement) that contains the event to be managed. For instance:

    Public Interface IConfiguration
        Event ConfigChanged(sender As Object, e As configPropertyChanged)
    End Interface

    In my case, I also create a class inheriting Event args.

    Public class configPropertyChanged
    Inherits EventArgs
        Public Property PropertyName() As string
        Public Property NewValue() As String
        Public Property OldValue() As String
        Public sub New(Newvalue as string,OldValue as string,<CallerMemberName()> optional PropertyName as string = "")
           Me.NewValue = Newvalue
           Me.OldValue =OldValue
           Me.PropertyName = PropertyName
        End sub
    End Class
  2. The configuration class is then modified to be able to monitor any class (which means that in the main module, the configuration must be made aware of the DataAccessManager class (Notice Idisposable is implemented to cleanup).

    Public Class Configuration
    Implements IDisposable
       Private _ConfigList As New List(Of IConfiguration)
        Public Sub RegisterConfig(Config As IConfiguration)
            AddHandler Config.ConfigChanged, AddressOf ConfigChanged
        End Sub
        Public Sub ConfigChanged(sender As Object, e As configPropertyChanged)
             Console.WriteLine("Config has changed.")
        End Sub
       #Region "IDisposable Support"
       Private disposedValue As Boolean ' To detect redundant calls
       Public Sub Dispose() Implements IDisposable.Dispose
           For Each config As IConfiguration In _ConfigList
           RemoveHandler config.ConfigChanged, AddressOf ConfigChanged
       End Sub
       #End Region
    End Class
  3. DataAccessManager does implement the Iconfiguration interface (available from common.dll)

    Public Class DataAccessMananger
       Implements IConfiguration
       Public Event ConfigChanged(sender As Object, e As configPropertyChanged) Implements IConfiguration.ConfigChanged
       Private _Name As String
       Public Property Name() As String
           Return _Name
        End Get
        Set(value As String)
           If String.Compare(_Name, value, True) <> 0 Then
               RaiseEvent ConfigChanged(Me, New configPropertyChanged(Value,_Name))
              _Name = value
           End If
        End Set
      End Property
    End Class
  4. Finally, the main module, which is the only one to be aware of the existence of both Configuration and DataAccessManager, register the DataAccessManager into the configuration.

    Public Sub Main()
       Dim MyManager As New DataAccessMananger
       Dim MyConfig As New Configuration
       MyManager.Name = "New name"
    End Sub

In this scenario. The main module load the configuration and the data access manager at some point and then, register the data access manager into the configuration object. It can also register any other class implementing the Iconfiguration process.

At some point, something triggers a raise event into the data access manager (In my example, changing the property name do exactly that). The data access manager raise the event, which the configuration object handles it since we registered the data class into the configuration object.

If you wanted, you could have skipped the interface entirely and just had the DataAccessManager raise an event to the main module, then in the main module event handler, call a public method from the configuration class.