簡體   English   中英

帶有Ninject的通用接口多次注入

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM