Reputation: 2604
I have a recurring pattern in my projects.
I have commands which publish eventaggregator-events and I have classes which explicitly subscribe to the events and handle them.
Problem: In the past I have referenced each and every eventhandler from my application root object to ensure that they get created and thus 'live' to be able to catch the event. Is there a way in which I do not have to do this with every event handling class? All the event handlers are named *EventHandler, if that could be of use...
I use Unity for IOC container.
Thanks for any input,
Anders, Denmark
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();
}
}
Edit: I've found a way to auto-instantiate -- but keep the question open; can it be done more elegantly?
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();
}
Upvotes: 2
Views: 829
Reputation: 6415
Just to clarify my comment with some code, when I use the Prism EventAggregator it will be in the following way:
// 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");
}
}
Upvotes: 1