2017-10-20 88 views
0

對於我正在開發的一個項目,我們正在實踐域驅動設計並將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://stackoverflow.com/a/46729694/1236044 – jbl

+0

我已經搬到遠離一個靜態事件調度程序,並讓我的域名返回事件。應用程序/整合層將發佈/引發事件,因爲另一個BC可能也對本BC中的事件感興趣,而不僅僅是同一BC中的其他聚合。你仍然需要一些機制來執行發佈,但是這些機制會被注入到你的控制器/應用程序層並從那裏被使用。只是一個雖然:) –

回答

0

而是在自己的代碼正確處理篩選的,你可以使用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