阅读this博客文章,它提到您可以让DI容器在实现IHandle<>
时自动订阅事件。这正是我想要实现的目标。
这是我到目前为止所拥有的。
container.Register(Component
.For<MainWindowViewModel>()
.ImplementedBy<MainWindowViewModel>()
.LifeStyle.Transient
.OnCreate((kernel, thisType) => kernel.Resolve<IEventAggregator>().Subscribe(thisType)));
虽然此代码成功订阅MainWindowViewModel
以接收已发布的消息,但实际接收消息的时间没有任何反应。如果我按预期手动订阅所有作品。
这是我的MainWindowViewModel
课程。
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);
}
}
如果任何类继承IHandle<>
?
我最终想出了这个订阅的自定义工具。
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);
}
}
}
查看Caliburn.Micro提供的EventAggregator
类我可以看到订阅成功,但是如果另一个类发布消息,MainWindowViewModel
类没有得到处理。手动订阅仍然有效,但我想自动化这个过程。我有一种感觉,它没有订阅正确的实例。但不知道如何解决这个问题。
我还尝试使用Kernel
属性公开的所有其他事件。他们中的大多数都无法解决IEventAggregator
。
我错过了什么?
答案 0 :(得分:3)
“我觉得它没有订阅正确的实例。不是 确定如何解决这个问题。“
您正在订阅实现的类型(System.Type的实例),而不是正在解析的实际依赖项。这一行:
aggregator.Subscribe(client.Implementation);
应该是
aggregator.Subscribe(dependency);
答案 1 :(得分:1)
您可能需要将IEventAggregator配置为单例。不知道究竟如何使用Windsor,但是使用ninject你会做类似
的事情Bind<IEventAggregator>().To<ConcreteEventAggregator>().InSingletonScope()
拥有单例将确保将所有事件聚合到单个基础字典(或您选择的数据类型)中,而不是每次解析IEventAggregator时都创建一个新事件。 HTH。
答案 2 :(得分:0)
这是如何实现Handler
public interface IHandle<TClass> : IHandle
{
void Handle(TClass Subscriber);
}
这是如何使用它..
public class MyViewModel : IHandle<SubscriberType >
{
public void Handle(SubscriberType Subscriber)
{
//Do something here.
}
}
答案 3 :(得分:0)
这可能已经很晚了,但这就是我能够实现它的方式
container.AddFacility<StartableFacility>();
container.Register(Component.For<ISubscriber<TagsProcessed>>()
.ImplementedBy<TagsProcessedListener>()
.OnCreate((kernel, instance) => eventAggregator.Subscribe(instance)).Start());