2015-01-09 66 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"); 
    } 
}