我在这里提出一个问题:Raising Domain Events For Multiple Subscribers并且答案引导我进入以下模式,我可以像这样拥有一个IEventPublisher:
public interface IEventPublisher<T>
{
void Publish(T data);
}
和像这样的IEventSubscriber:
public interface IEventSubscriber<T>
{
void Handle(T data);
}
这个问题是我需要将每个发布者的实例传递给构造函数,如下所示:
public Service(IEventPublisher<ThingyChangedEvent> publisherThingyChanged)
{
// Set publisher to local variable
}
// then call this in a method
_publisherThingyChanged.Publish(new ThingyChangedEvent { ThingyId = model.Id});
我希望能够做的是拥有一个包含任何IEventPublishers的通用发布者,所以我可以调用类似的东西:
_genericPublisher.Publish(new ThingyChangedEvent { ThingyId = model.Id});
我无法弄清楚如何做到这一点,因为我无法传递IEventPublisher的集合而不定义T,因为在此示例中为ThingyChangedEvent,而我想要的是根据传递给的类型来确定发布者通用出版商。
任何建议都非常感谢。
修改
确定使用下面的答案和来自这里的一些信息:http://www.udidahan.com/2009/06/14/domain-events-salvation/我想出了以下内容,但它并不完全存在:
public interface IEventManager
{
void Publish<T>(T args) where T : IEvent;
}
public class EventManager:IEventManager { Autofac.ILifetimeScope _container;
public EventManager(Autofac.ILifetimeScope container)
{
_container = container;
}
//Registers a callback for the given domain event
public void Publish<T>(T args) where T : IEvent
{
var subscribersProvider = _container.Resolve<IEventSubscribersProvider<T>>();
foreach (var item in subscribersProvider.GetSubscribersForEvent())
{
item.Handle(args);
}
}
}
我现在可以在autofac解析的构造函数中获取IEventManager eventManager的实例,并按如下方式调用它:
_eventManager.Publish<ThingyChangedEvent>(new ThingyChangedEvent() { ThingyId = Guid.NewGuid() });
以下是我对此解决方案不喜欢的内容:
我不想在构造函数中使用ILifetimeScope的实例,我希望能够获取IEventSubscribersProvider的集合,但如果我要求说,autofac将无法解决此问题:
IEnumerable<IEventSubscribersProvider<IEvent>>
如果我将类型传递给Publish并调用:
,我只能解决它Resolve<IEventSubscribersProvider<T>>.
第二个问题不是一个大问题,但能够调用发布而不必像这样传递类型会很好:
_eventManager.Publish(new ThingyChangedEvent() { ThingyId = Guid.NewGuid() });
我认为如果有人对如何解决这两个问题有任何建议,特别是问题1,因为我不喜欢在不同的项目中依赖Autofac。我能想到的唯一一个是某种类型的管理器类,它明确地采用了我需要的内容如下:
public SomeConstructor(
IEventSubscribersProvider<ThingyChangedEvent> thingChangedSubscribeProviders,
IEventSubscribersProvider<SomeOtherEvent> someOtherSubscribeProviders,
etc....)
{
// Maybe take the EventManager as well and add them to it somehow but would be
// far easier to take a collection of these objects somehow?
}
非常感谢任何建议。
编辑2
经过大量研究并观察Autofac Generic Service resolution at runtime后,我不确定自己能达到什么目的。我能想出的最佳解决方案是:
public interface IEventSubscribersProviderFactory : Amico.IDependency
{
IEventSubscribersProvider<T> Resolve<T>() where T : IEvent;
}
public class EventSubscribersProviderFactory : IEventSubscribersProviderFactory
{
Autofac.ILifetimeScope _container;
public EventSubscribersProviderFactory(Autofac.ILifetimeScope container)
{
_container = container;
}
public IEventSubscribersProvider<T> Resolve<T>() where T : IEvent
{
return _container.Resolve<IEventSubscribersProvider<T>>();
}
}
然后让EventManager在构造函数中使用IEventSubscribersProviderFactory来删除该项目对Autofac的依赖。
我现在要继续这样做,但希望能长期找到更好的解决方案。