通用接口多注入与Ninject

问题描述:

对于我正在开发的一个项目,我们正在实践域驱动设计并将ninject用作我们的IOC容器。我试图实施类似于Tony Truong here所述方法的域事件。我正在尝试使用ninject,而不必在组合根之外拥有静态服务或引用内核。我试图做这样的事情通用接口多注入与Ninject

/// <summary> 
/// Service to dispatch domain events to handlers. 
/// </summary> 
public class NinjectDomainEventDispatcher : IDomainEventDispatcher 
{ 
    /// <summary> 
    /// Array containing domain event handler registrations. 
    /// </summary> 
    private readonly IDomainEventHandler<IDomainEvent>[] _handlers; 

    /// <summary> 
    /// Initializes a new instance of the <see cref="NinjectDomainEventDispatcher"/> class. 
    /// </summary> 
    /// <param name="handlers">Registered domain event handlers.</param> 
    public NinjectDomainEventDispatcher(IDomainEventHandler<IDomainEvent>[] handlers) 
    { 
     _handlers = handlers; 
    } 

    /// <summary> 
    /// Dispatch domain event to subscribed handlers. 
    /// </summary> 
    /// <typeparam name="T">Type of domain event to dispatch.</typeparam> 
    /// <param name="domainEvent">Domain event to dispatch.</param> 
    public void Dispatch<T>(T domainEvent) where T : IDomainEvent 
    { 
     foreach (var handler in _handlers.Where(x => x.GetType() == typeof(IDomainEventHandler<T>))) 
     { 
      handler.Handle(domainEvent); 
     } 
    } 
} 

/// <summary> 
/// Module that will be used for the registration of the domain event handlers 
/// </summary> 
public class DomainEventHandlerModule : NinjectModule 
{ 
    /// <summary> 
    /// The method that will be used to load the ninject registration information. 
    /// </summary> 
    public override void Load() 
    { 
     Bind<IDomainEventDispatcher>().To<NinjectDomainEventDispatcher>(); 
     Bind<IDomainEventHandler<ConcreteDomainEvent>>().To<ConcreteDomainEventHandler1>(); 
     Bind<IDomainEventHandler<ConcreteDomainEvent>>().To<ConcreteDomainEventHandler2>(); 
     Bind<IDomainEventHandler<AnotherConcreteDomainEvent>>().To<AnotherConcreteDomainEventHandler1>(); 
     Bind<IDomainEventHandler<AnotherConcreteDomainEvent>>().To<AnotherConcreteDomainEventHandler2>(); 
    } 
} 

目的是呼吁到调度方法传递域事件实例的类型注册的所有处理程序。我的问题是,注入处理程序数组是空的(我猜,因为它是专门寻找处理程序绑定到IDomainEventHandler <IDomainEvent>,而不是所有类型的实现IDomainEvent像我需要)。

+0

最近这次的回答可以帮助你的问题似乎真的与你相似https://*.com/a/46729694/1236044 – jbl

+0

我已经搬到远离一个静态事件调度程序,并让我的域名返回事件。应用程序/整合层将发布/引发事件,因为另一个BC可能也对本BC中的事件感兴趣,而不仅仅是同一BC中的其他聚合。你仍然需要一些机制来执行发布,但是这些机制会被注入到你的控制器/应用程序层并从那里被使用。只是一个虽然:) –

而是在自己的代码正确处理筛选的,你可以使用ninject来为你做的:

public class NinjectDomainEventDispatcher : IDomainEventDispatcher 
{ 
    private readonly IResolutionRoot resolutionRoot; 

    public NinjectDomainEventDispatcher(IResolutionRoot resolutionRoot) 
    { 
     this.resolutionRoot = resolutionRoot; 
    } 

    public void Dispatch<T>(T domainEvent) where T : IDomainEvent 
    { 
     var handlers = this.resolutionRoot.GetAll<IDomainEventHandler<T>>(); 
     foreach (var handler in handlers) 
     { 
      handler.Handle(domainEvent); 
     } 
    } 
} 

专业提示:推荐的设计实践是将依赖于IResolutionRoot代码(Ninject )到composition root的工厂实施。 除了手动做这个的,你也可以利用Ninject.Extensions.Factory