为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
扬帆大鱼 2021-05-14 18:19:36
我的目标是在并行线程中运行永无止境的进程。问题是,我不能仅在新线程中实例化我的辅助服务,因为我在应用程序中使用了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在工作线程中实例化我?这听起来像一场噩梦!是否有更好的方法或更有效的方法来实现这一目标?
查看完整描述

1 回答

?
慕丝7291255

TA贡献1859条经验 获得超6个赞

这是否意味着我需要约60多个抽象工厂才能IQueueProcessor在工作线程中实例化我?


在最坏的情况下,可能需要这样做。当所有依赖项都必须具有瞬态生存期时(例如,它们不是线程安全的),可能会发生这种情况。


但是,在最佳情况下,所有这些依赖项都可能具有Singleton生存期,这可能适用于线程安全的依赖项。在这种情况下,不需要内部工厂:


public class QueueProcessorFactory : IQueueProcessorFactory

{

    private readonly IEventTriggerQueuedEventService _qeueuedEventService;    

    private readonly ILogger _logger;    

    private readonly IEventTriggerActionGroupLogService _eventTriggerActionGroupLogService;

    // etc...


    public QueueProcessorFactory(

        IEventTriggerQueuedEventService qeueuedEventService,

        ILogger logger,

        IEventTriggerActionGroupLogService eventTriggerActionGroupLogService,

        /* etc... */)

    {

        _qeueuedEventService = qeueuedEventService;

        _logger = logger;

        _eventTriggerActionGroupLogService = eventTriggerActionGroupLogService;

        // etc...

    }


    public IQueueProcessor Create()

    {

        return new QueueProcessor(

            _qeueuedEventService,

            _logger,

            _eventTriggerActionGroupLogService,

            /* etc... */);

    }

}

实际上,您可能需要将一些Transient依赖项(需要工厂)与一些Singleton依赖项混合在一起。


如果最终需要数十家工厂,则可以考虑使用DI容器。其中一些可以自动生成工厂接口的实现-您只需提供他们必须实现的接口即可。


此外,您不必为每个依赖项定义一个接口,而是可以考虑使用一个通用接口,例如:


public interface IFactory<T>

{

    T Create();

}

再次,一些DI容器在那里支持此类工厂。您也可以考虑完全放弃接口,而只使用像这样的委托Func<T>。


但是,除非情况特殊,否则我不建议您使用DI容器,而是推荐Pure DI。当您使用DI容器时,您将失去编译时的安全性,我倾向于认为这不值得取舍。毕竟,编程的瓶颈很少是您的打字速度。


查看完整回答
反对 回复 2021-05-23
  • 1 回答
  • 0 关注
  • 156 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信