![](/img/trans.png)
[英]Ninject multi-injection is not as greedy as I would have thought! How come?
[英]Generic Interface Multi-Injection with Ninject
對於我正在從事的項目,我們正在實踐域驅動設計,並將ninject用作我們的IOC容器。 我正在嘗試實現類似於Tony Truong 在此處描述的方法的領域事件。 我正在嘗試使用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>();
}
}
目標是調用為傳遞給Dispatch方法的域事件實例的類型注冊的所有處理程序。 我的問題是,注入時處理程序數組為空(我猜是因為它專門查找綁定到IDomainEventHandler <IDomainEvent>的處理程序,而不是像我需要的那樣,並非所有實現IDomainEvent類型的處理程序)。
您可以使用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);
}
}
}
Pro-Tip:建議的設計實踐是將依賴於IResolutionRoot
(Ninject)的代碼移動到composition root中的工廠實現。 除了手動執行此操作外,您還可以使用Ninject.Extensions.Factory
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.