DryIOC 事件聚合器

标签 dryioc

我正在尝试使用 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);
        }
    }
}

我有许多可以处理事件的类。由以下接口(interface)指示:

public interface IHandles<T> where T : System.EventArgs
{
    void Handle(T args);
}

它的要点是,当我调用事件调度程序调度方法时,并传入一个继承自 EventArgs 的类型。它从 IOC 容器中获取所有实现 IHandles<> 的类型并对其调用 handle 方法。

一个事件类型可以由多个服务处理。一个服务可以处理多种事件类型。例如:

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");
    }
}

服务需要做其他事情以及处理事件(但可能没有其他接口(interface),因为它们不是必需的)。 有些服务需要单例,事件的处理要尊重单例注册。因此,对 container.Resolve(IHandles<>) 的调用应该返回该服务的 Singleton 类型,而不是生成多个实例。这些服务从多个来源收集事件,因此需要在将它们发送到其他地方之前维护内部状态。因此,调用不同服务的不同事件处理程序需要发送到相同的底层实例。

我希望能够将 IHandles 接口(interface)添加到任何服务,并自动获取它,而不必每次都摆弄 IOC 映射。理想情况下,还应使用基于约定的映射来添加服务类型。

到目前为止,我已经为此工作了两天。我放弃了尝试用结构图来实现它。现在我正在尝试 DryIOC - 但发现它更难理解和正确。

最佳答案

DryIoc 中很容易做到(我是业主)。这里我要说的是V2 RC版。

假设您已经替换了 IContainerIResolver 的依赖关系这是自动注入(inject)的:

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<> 返回相同的实例接口(interface)。

另外你可以使用 RegisterMapping添加/映射 IHandles<>服务于已注册的实现。

DryIoc 甚至有 more帮助实现 EventAggregator。

这也是 problem similar to yours 的解决方案.

gist with your working example .

关于DryIOC 事件聚合器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32631325/

相关文章:

c# - 如何将依赖项从测试项目传递到 DryIoc 中的具体实现

c# - DryIoc 构造函数参数重用

logging - 在 DryIoc 容器中注册 ILoggerFactory

c# - 将 HostBuilder.ConfigureServices 与 DryIoc 容器一起使用?

c# - DryIoc 用函数解析

c# - 使用 DryIoc 解决多个注册之一

generics - DryIoC 根据泛型类型参数将参数传递给开放泛型服务的构造函数

c# - 如何在 Prism 中向 IoC 注册类

DryIoc Register接口(interface)的多种实现