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();
}
你到底想达到什么目的?无论如何,如果你想处理这些事件,你需要订阅。您可以使用反射来获取所有'EventHandler'类型(类),创建实例并执行订阅作业,但我不建议这样做。这很难保持和测试。 – dymanoid
嗨dymanoid, 我希望实现,我避免引用我的应用程序根或子对象中的每个事件处理程序。通过自动实例化事件处理程序,我可以引入新的事件和事件处理程序,并让它们毫不费力地工作。 –
我不太清楚你遇到了什么问题,当我使用'EventAggregator'时,我当然不必引用应用程序根目录中的每个事件处理程序。我的各种虚拟机的构造函数都使用Unity IoC处理'EventAggregator',并订阅他们感兴趣的任何事件(在我的情况下,在它们的构造函数中)。大多数这些虚拟机只能根据正在运行的程序中的用户交互来创建。然后他们能够回应各种其他Vms发布的事件。 – Mashton