2016-05-20 4 views
1

У меня есть приложение.VB.NET Управлять событием от одного класса в другом, если они не знают друг друга ...?

Module1 - Основное применение

DataAccessMananger - класс в главном приложении для обработки данных

Конфигурации - класс в другом проекте (общий DLL), которая обрабатывает параметры конфигурации.

Проблема/вопрос. Как класс Configuration обрабатывает событие с изменениями данных в DataAccessManager, не зная, что такое DataAccessManager, поскольку они находятся в разных классах?

Единственный способ, с помощью которого я могу заставить его работать, состоит в том, чтобы модуль 1 обрабатывал событие из DataAccessManager и вызывал его метод в классе Configuration, однако мне не нравится это, я бы предпочел, чтобы конфигурация могла обрабатывать его собственные обновления данных ...

Очистить как грязь? Есть идеи? VB.NET 4.5, и я немного знаю о делегатах, но не знаю, как я могу их использовать здесь, они должны быть ответом, как ...

В идеале, я хотел бы иметь возможность передать «Событие» "в класс конфигурации из класса DAM с помощью модуля ...

+0

Пожалуйста, проверьте это [URL] (http://stackoverflow.com/help), будет полезно повысить качество вашего контента. –

+1

Технически, когда object1 обрабатывает событие объекта2, на самом деле происходит то, что создается делегат это относится к методу в объекте1 и что делегат передается объекту2, который хранит его в коллекции. Object2, создающий событие, фактически состоит из того, что он проходит через эту коллекцию делегатов и вызывает их. Таким образом, вполне возможно, что ваши два класса ничего не знают друг о друге, и один из них по-прежнему обрабатывает событие другого, если существует какой-то другой тип, который знает обо всех них и способен создавать и передавать делегировать. – jmcilhinney

+0

Я уверен, что вы не можете этого сделать, если не можете изменить и скомпилировать новую версию Common.dll. Оттуда вы можете создавать методы, которые позволят вам динамически добавлять прослушиватели событий. Боюсь, вы застряли в том, что ваш модуль подписался на это событие и вызвал метод в классе Config. –

ответ

1

Лучший способ, я могу думать, это добавить интерфейс в классе конфигурации (common.dll), который будет реализован DataAccessManager. Я предполагаю, что mainmodule знает как DataAccessMananger, так и конфигурацию, правильно? Если это так, то решение может быть следующим.

  1. Добавить интерфейс к common.dll для используемого (не реализуемого) класса Configuration, который содержит управляемое событие. Например:

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

    В моем случае я также создаю класс, наследующий 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. Класс конфигурации затем модифицируется, чтобы иметь возможность контролировать любой класс (что означает, что в основном модуле, конфигурация должна быть осведомлена о классе DataAccessManager (Примечание IDisposable реализуется для очистки).

    Public Class Configuration 
    Implements IDisposable 
        Private _ConfigList As New List(Of IConfiguration) 
    
        Public Sub RegisterConfig(Config As IConfiguration) 
         _ConfigList.Add(Config) 
         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 
        Next 
        _ConfigList.clear() 
        End Sub 
        #End Region 
    
    End Class 
    
  3. DataAccessManager делает реализовывать интерфейс IConfiguration (доступный от 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 
        Get 
         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. Наконец, основной модуль, который является единственным, кто должен знать о существовании как Configuration, так и DataAccessManager, зарегистрирует DataAccessManager в конфигурации.

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

В этом сценарии. Основной модуль загружает конфигурацию и диспетчер доступа к данным в какой-то момент, а затем регистрирует диспетчер доступа к данным в объект конфигурации. Он также может зарегистрировать любой другой класс, реализующий процесс Iconfiguration.

В какой-то момент что-то вызывает событие повышения в диспетчере доступа к данным (в моем примере изменение имени свойства делает именно это). Менеджер доступа к данным поднимает событие, которое обрабатывает объект конфигурации, так как мы зарегистрировали класс данных в объекте конфигурации.

Если вы хотите, вы могли бы полностью пропустить интерфейс и просто заставить DataAccessManager поднять событие к основному модулю, а затем в обработчике событий основного модуля вызвать общедоступный метод из класса конфигурации.

Смежные вопросы