使用依赖注入实例化工作线程中的对象

我的目标是在并行线程中运行永无止境的进程。问题是,我不能仅在新线程中实例化我的辅助服务,因为我在应用程序中使用了DI。


根据我在SO上的研究,我注意到许多人建议将抽象工厂注入线程中,以便在并行线程中动态实例化线程安全对象。1,2


/// <summary>

/// Responsible for starting parallel long running worker threads

/// </summary>

public class ParallelWorkerStarter

{

    private readonly IQueueProcessorFactory _queueProcessorFactory;


    public ParallelWorkerStarter(IQueueProcessorFactory queueProcessorFactory)

    {

        _queueProcessorFactory = queueProcessorFactory;

    }


    public void StartQueueProcessorThread()

    {    

        queueProcessor = new Thread(

        () =>

        {

            _queueProcessorFactory.Create().ProcessQueue();

        })

        { Name = "QueueProcessor" };

        queueProcessor.Start();

    }

}

的Abstract FactoryIQueueProcessorFactory看起来像这样:


/// <summary>

/// Abstract factory responsible for producing an <see cref="IQueueProcessor"/>

/// </summary>

/// <remarks>

///  This abstract factory is used to generate an <see cref="IQueueProcessor"/> In a seperate thread. 

///  Therefore, all of its dependencies also need to be dynamically generated

/// </remarks>

public interface IQueueProcessorFactory

{

    /// <summary>

    /// Dynamically creates ab <see cref="IQueueProcessor"/>

    /// </summary>

    /// <returns>

    /// The <see cref="IQueueProcessor"/>.

    /// </returns>

    IQueueProcessor Create();

}

现在,我的主要问题是,QueueProcessor实现的具体对象IQueueProcessor具有11个依赖项(我知道SRP代码的味道),每个依赖项本身都有5-6个依赖项。

这是否意味着我需要约60多个抽象工厂才能IQueueProcessor在工作线程中实例化我?这听起来像一场噩梦!是否有更好的方法或更有效的方法来实现这一目标?


扬帆大鱼
浏览 157回答 1
1回答

慕丝7291255

这是否意味着我需要约60多个抽象工厂才能IQueueProcessor在工作线程中实例化我?在最坏的情况下,可能需要这样做。当所有依赖项都必须具有瞬态生存期时(例如,它们不是线程安全的),可能会发生这种情况。但是,在最佳情况下,所有这些依赖项都可能具有Singleton生存期,这可能适用于线程安全的依赖项。在这种情况下,不需要内部工厂:public class QueueProcessorFactory : IQueueProcessorFactory{&nbsp; &nbsp; private readonly IEventTriggerQueuedEventService _qeueuedEventService;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; private readonly ILogger _logger;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; private readonly IEventTriggerActionGroupLogService _eventTriggerActionGroupLogService;&nbsp; &nbsp; // etc...&nbsp; &nbsp; public QueueProcessorFactory(&nbsp; &nbsp; &nbsp; &nbsp; IEventTriggerQueuedEventService qeueuedEventService,&nbsp; &nbsp; &nbsp; &nbsp; ILogger logger,&nbsp; &nbsp; &nbsp; &nbsp; IEventTriggerActionGroupLogService eventTriggerActionGroupLogService,&nbsp; &nbsp; &nbsp; &nbsp; /* etc... */)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; _qeueuedEventService = qeueuedEventService;&nbsp; &nbsp; &nbsp; &nbsp; _logger = logger;&nbsp; &nbsp; &nbsp; &nbsp; _eventTriggerActionGroupLogService = eventTriggerActionGroupLogService;&nbsp; &nbsp; &nbsp; &nbsp; // etc...&nbsp; &nbsp; }&nbsp; &nbsp; public IQueueProcessor Create()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return new QueueProcessor(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _qeueuedEventService,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _logger,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _eventTriggerActionGroupLogService,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* etc... */);&nbsp; &nbsp; }}实际上,您可能需要将一些Transient依赖项(需要工厂)与一些Singleton依赖项混合在一起。如果最终需要数十家工厂,则可以考虑使用DI容器。其中一些可以自动生成工厂接口的实现-您只需提供他们必须实现的接口即可。此外,您不必为每个依赖项定义一个接口,而是可以考虑使用一个通用接口,例如:public interface IFactory<T>{&nbsp; &nbsp; T Create();}再次,一些DI容器在那里支持此类工厂。您也可以考虑完全放弃接口,而只使用像这样的委托Func<T>。但是,除非情况特殊,否则我不建议您使用DI容器,而是推荐Pure DI。当您使用DI容器时,您将失去编译时的安全性,我倾向于认为这不值得取舍。毕竟,编程的瓶颈很少是您的打字速度。
打开App,查看更多内容
随时随地看视频慕课网APP