2015-01-09 92 views
0

我的項目中有反覆出現的模式。如何在棱鏡中創建事件訂閱者(eventaggregator)

我有發佈eventaggregator事件的命令,我有明確訂閱事件並處理它們的類。

問題:在過去,我從應用程序根對象中引用了每個事件處理程序,以確保它們被創建並因此能夠「捕捉」事件。有沒有辦法讓我不必爲每個事件處理類都做這件事? 所有的事件處理程序被命名爲* EventHandler,如果可以使用...

我使用Unity for IOC容器。

感謝您的任何輸入,

安德斯,丹麥

public class PickWishListCommand : BaseCommand, IPickWishListCommand 
 
    { 
 
     private readonly IEventAggregator _eventAggregator; 
 

 
     public PickWishListCommand(IEventAggregator eventAggregator) 
 
     { 
 
      _eventAggregator = eventAggregator; 
 
     } 
 

 
     public bool CanExecute(object parameter) 
 
     { 
 
      return true; 
 
     } 
 

 
     public void Execute(object parameter) 
 
     { 
 
      _eventAggregator 
 
       .GetEvent<PickWishListEvent>() 
 
       .Publish(parameter); 
 
     } 
 
    } 
 

 
    public class PickWishListEventHandler : IPickWishListEventHandler 
 
    { 
 
     public PickWishListEventHandler(IEventAggregator eventAggregator) 
 
     { 
 
      eventAggregator.GetEvent<PickWishListEvent>().Subscribe(OnEvent); 
 
     } 
 

 
     private void OnEvent(object obj) 
 
     { 
 
      throw new System.NotImplementedException(); 
 
     } 
 
    } 
 

 
public partial class App 
 
{ 
 
    protected override void OnStartup(StartupEventArgs e) 
 
    { 
 
     base.OnStartup(e); 
 

 
     var container = new UnityContainer(); 
 
     container 
 
      .RegisterTypes(
 
       AllClasses.FromAssembliesInBasePath(), 
 
       WithMappings.FromMatchingInterface, 
 
       WithName.Default, 
 
       WithLifetime.ContainerControlled); 
 

 
     var executionContext = container.Resolve<IExecutionContext>(); 
 
     var configurationApplicationService = container.Resolve<IConfigurationApplicationService>(); 
 

 
     configurationApplicationService.SetupMainWindow(); 
 

 
     //Thread.Sleep(3000); 
 
     var mainWindow = new MainWindow 
 
     { 
 
      DataContext = executionContext.MainWindowViewModel 
 
     }; 
 
     mainWindow.Show(); 
 
    } 
 
}

編輯:我已經找到一種方法來自動實例化 - 但保持開放的問題;它可以做得更優雅嗎?

 protected override void OnStartup(StartupEventArgs e) 
 
     { 
 
      base.OnStartup(e); 
 

 
      var container = new UnityContainer(); 
 
      container 
 
       .RegisterTypes(
 
        AllClasses.FromAssembliesInBasePath(), 
 
        WithMappings.FromMatchingInterface, 
 
        WithName.Default, 
 
        WithLifetime.ContainerControlled); 
 

 
      var eventHandlers = new List<object>(); 
 

 
      foreach (var registration in container.Registrations) 
 
      { 
 
       var nameOfRegType = registration.RegisteredType.Name; 
 
       var overrides = new ResolverOverride[] { }; 
 
       if (!nameOfRegType.EndsWith("EventHandler") || !nameOfRegType.StartsWith("I")) continue; 
 

 
       var t = container.Resolve(registration.RegisteredType, overrides); 
 
       eventHandlers.Add(t); 
 
      } 
 
      var executionContext = container.Resolve<IExecutionContext>(); 
 
      executionContext.EventHandlers = eventHandlers; 
 

 
      var configurationApplicationService = executionContext.ConfigurationApplicationService; 
 
      configurationApplicationService.SetupMainWindow(); 
 

 
      var mainWindow = new MainWindow 
 
      { 
 
       DataContext = executionContext.MainWindowViewModel 
 
      }; 
 

 
      mainWindow.Show(); 
 
     }

+0

你到底想達到什麼目的?無論如何,如果你想處理這些事件,你需要訂閱。您可以使用反射來獲取所有'EventHandler'類型(類),創建實例並執行訂閱作業,但我不建議這樣做。這很難保持和測試。 – dymanoid

+0

嗨dymanoid, 我希望實現,我避免引用我的應用程序根或子對象中的每個事件處理程序。通過自動實例化事件處理程序,我可以引入新的事件和事件處理程序,並讓它們毫不費力地工作。 –

+0

我不太清楚你遇到了什麼問題,當我使用'EventAggregator'時,我當然不必引用應用程序根目錄中的每個事件處理程序。我的各種虛擬機的構造函數都使用Unity IoC處理'EventAggregator',並訂閱他們感興趣的任何事件(在我的情況下,在它們的構造函數中)。大多數這些虛擬機只能根據正在運行的程序中的用戶交互來創建。然後他們能夠迴應各種其他Vms發佈的事件。 – Mashton

回答

1

只是爲了澄清我的一些代碼註釋,當我用棱鏡EventAggregator它會以下列方式:

// A library class holding event classes 
public class ThisClassDefinesMyEvents 
{ 
    public class MyImportantEvent : CompositePresentationEvent<string>{}; 
} 

// An example viewmodel, that subscribes to an event 
public class SomeRecievingVm 
{ 
    private readonly IEventAggregator _eventAggregator; 
    public SomeRecievingVm(IEventAggregator eventAggregator) 
    { 
    _eventAggregator = eventAggregator; 
    _eventAggregator.GetEvent<MyImportantEvent>().Subscribe(MyEventHandlingMethod); 
    } 

    public void MyEventHandlingMethod(string whatHappened) 
    { 
    Console.WriteLine(whatHappened); 
    } 
} 

// An example VM that publishes an event, under a couple of different circumstances 
public class SomeSendingVm 
{ 
    private readonly IEventAggregator _eventAggregator; 
    public SomeSendingVm(IEventAggregator eventAggregator) 
    { 
    _eventAggregator = eventAggregator; 
    _eventAggregator.GetEvent<MyImportantEvent>().Publish("I am alive"); 
    } 

    private void SomeMethodThatHappensSometimes() 
    { 
    _eventAggregator.GetEvent<MyImportantEvent>().Publish("I've done something"); 
    } 
}