Reading this blog post it mentions you can get your DI container to automatically subscribe to events if it implements IHandle<>
. That is exactly what I'm trying to accomplish.
Here is what I have so far.
container.Register(Component
.For<MainWindowViewModel>()
.ImplementedBy<MainWindowViewModel>()
.LifeStyle.Transient
.OnCreate((kernel, thisType) => kernel.Resolve<IEventAggregator>().Subscribe(thisType)));
While this code is successfully subscribing MainWindowViewModel
to receive published messages, come time to actually receive messages nothing happens. If I manually subscribe all works as expected.
Here is my MainWindowViewModel
class.
public class MainWindowViewModel : IHandle<SomeMessage>
{
private readonly FooViewModel _fooViewModel;
private readonly IEventAggregator _eventAggregator;
public MainWindowViewModel(FooViewModel fooViewModel, IEventAggregator eventAggregator)
{
_fooViewModel = fooViewModel;
_eventAggregator = eventAggregator;
//_eventAggregator.Subscribe(this);
_fooViewModel.InvokeEvent();
}
public void Handle(SomeMessage message)
{
Console.WriteLine("Received message with text: {0}", message.Text);
}
}
How can I tell Windsor to automatically subscribe if any class inherits IHandle<>
?
I ended up coming up with this custom facility that subscribes.
public class EventAggregatorFacility : AbstractFacility
{
protected override void Init()
{
Kernel.DependencyResolving += Kernel_DependencyResolving;
}
private void Kernel_DependencyResolving(ComponentModel client, DependencyModel model, object dependency)
{
if(typeof(IHandle).IsAssignableFrom(client.Implementation))
{
var aggregator = Kernel.Resolve<IEventAggregator>();
aggregator.Subscribe(client.Implementation);
}
}
}
Looking at the EventAggregator
class provided by Caliburn.Micro I'm able to see that the subcription is successful, however if another class publishes a message the MainWindowViewModel
class isn't getting getting handled. Manually subscribing still works but I'd like to automate this process. I have a feeling that it's not subscribing the correct instance. Not sure how to fix that, though.
I've also tried using every other event exposed by the Kernel
property. Most of them can't resolve IEventAggregator
.
What am I missing?