我在这里提出了一个问题: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;
}
公共类 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 通用服务解决方案后,我不确定我能否实现我想要的。我能想出的最佳解决方案是:
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 的依赖。
我现在会这样做,但希望能找到一个更好的长期解决方案。