我正在尝试使用DryIOC实现事件聚合器。我有一个事件调度员如下:
public class DryIocEventDispatcher : IEventDispatcher
{
private readonly IContainer _container;
public DryIocEventDispatcher(IContainer container)
{
_container = container;
}
public void Dispatch<TEvent>(TEvent eventToDispatch) where TEvent : EventArgs
{
foreach (var handler in _container.ResolveMany<IHandles<TEvent>>())
{
handler.Handle(eventToDispatch);
}
}
}
我有很多可以处理事件的类。由以下界面指示:
public interface IHandles<T> where T : System.EventArgs
{
void Handle(T args);
}
它的要点是,当我调用事件调度程序调度方法时,传入一个继承自EventArgs的类型。它从IOC容器中获取,实现IHandles的所有类型&lt;&gt;并在它们上调用handle方法。
事件类型可由多个服务处理。服务可以处理多种事件类型。 e.g:
public class ScoringService : IHandles<ZoneDestroyedEventArgs>, IHandles<ZoneCreatedEventArgs>
{
public void Handle(ZoneDestroyedEventArgs args)
{
Console.WriteLine("Scoring Service Handled ZoneDestroyed Event");
}
public void Handle(ZoneCreatedEventArgs args)
{
Console.WriteLine("Scoring Service Handled ZoneCreated Event");
}
}
public class RenderingService : IHandles<ZoneDestroyedEventArgs>, IHandles<ZoneCreatedEventArgs>
{
public void Handle(ZoneDestroyedEventArgs args)
{
Console.WriteLine("Rendering Service Handled ZoneDestroyed Event");
}
public void Handle(ZoneCreatedEventArgs args)
{
Console.WriteLine("Rendering Service Handled ZoneCreated Event");
}
}
服务需要做其他事情以及处理事件(但可能没有其他接口,因为它们不是必需的)。 某些服务需要是单身,事件处理应尊重单身注册。因此,对container.Resolve(IHandles&lt;&gt;)的调用应返回该服务的Singleton类型,而不是多个实例。这些服务从多个来源收集事件,因此需要在将其发送到其他地方之前保持内部状态。因此,需要将调用不同服务的不同事件处理程序发送到同一个底层实例。
我希望能够将IHandles接口添加到任何服务中,并且可以自动拾取它,而不必每次都使用IOC映射。理想情况下,也应使用基于约定的映射添加服务类型。
到目前为止,我已经为此工作了两天。我放弃了尝试使用structuremap实现它。现在我正在尝试DryIOC - 但发现它更难以理解并且正确。
答案 0 :(得分:2)
DryIoc(我是老板)很容易做到。在这里,我将谈论V2 RC版本。
鉴于您已将IContainer
依赖项替换为IResolver
,并自动注入:
var container = new Container();
container.Register<IEventDispatcher, DryIocEventDispatcher>();
container.RegisterMany<ScoringService>(Reuse.Singleton);
container.RegisterMany<RenderingService>();
var eventDispatcher = container.Resolve<IEventDispatcher>();
eventDispatcher.Dispatch(new ZoneDestroyedEventArgs());
eventDispatcher.Dispatch(new ZoneCreatedEventArgs());
RegisterMany将负责将处理程序重用为 Singleton ,并为两个Handles<>
接口返回相同的实例。
此外,您可以使用RegisterMapping向已注册的实施添加/映射IHandles<>
服务。
DryIoc甚至可以more来帮助实现EventAggregator。
这里也是problem similar to yours的解决方案。