gpt4 book ai didi

c# - 使用依赖注入(inject)在工作线程中实例化对象

转载 作者:行者123 更新时间:2023-11-30 16:40:56 25 4
gpt4 key购买 nike

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

根据我对 SO 的研究,我注意到很多人建议需要将抽象工厂注入(inject)到线程中,以在并行线程中动态实例化线程安全对象。 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();
}
}

IQueueProcessorFactory 的抽象工厂如下所示:

/// <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();
}

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

/// <inheritdoc />
public class QueueProcessorFactory : IQueueProcessorFactory
{
private readonly IEventTriggerQueuedEventServiceFactory _qeueuedEventServiceFactory;

private readonly ILoggerFactory _loggerFactory;

private readonly IEventTriggerActionGroupLogServiceFactory _eventTriggerActionGroupLogServiceFactory;

private readonly IExceptionLogServiceFactory _exceptionLogServiceFactory;

private readonly IEventTriggerServiceFactory _eventTriggerServiceFactory;

private readonly IConditionServiceFactory _conditionServiceFactory;

private readonly IEventTriggerActionServiceFactory _eventTriggerActionServiceFactory;

private readonly IEngineEnabledCheckerFactory _engineEnabledCheckerFactory;

private readonly IEventTriggerScheduleSetServiceFactory _eventTriggerScheduleSetServiceFactory;

private readonly IEventTriggerActionResultServiceFactory _eventTriggerActionResultServiceFactory;

private readonly IWorkflowExceptionHandlerFactory _workflowExceptionHandlerFactory;

public QueueProcessorFactory(
IEventTriggerQueuedEventServiceFactory qeueuedEventServiceFactory,
ILoggerFactory loggerFactory,
IEventTriggerActionGroupLogServiceFactory eventTriggerActionGroupLogServiceFactory,
IExceptionLogServiceFactory exceptionLogServiceFactory,
IEventTriggerServiceFactory eventTriggerServiceFactory,
IConditionServiceFactory conditionServiceFactory,
IEventTriggerActionServiceFactory eventTriggerActionServiceFactory,
IEngineEnabledCheckerFactory engineEnabledCheckerFactory,
IEventTriggerScheduleSetServiceFactory eventTriggerScheduleSetServiceFactory,
IEventTriggerActionResultServiceFactory eventTriggerActionResultServiceFactory,
IWorkflowExceptionHandlerFactory workflowExceptionHandlerFactory)
{
_qeueuedEventServiceFactory = qeueuedEventServiceFactory;
_loggerFactory = loggerFactory;
_eventTriggerActionGroupLogServiceFactory = eventTriggerActionGroupLogServiceFactory;
_exceptionLogServiceFactory = exceptionLogServiceFactory;
_eventTriggerServiceFactory = eventTriggerServiceFactory;
_conditionServiceFactory = conditionServiceFactory;
_eventTriggerActionServiceFactory = eventTriggerActionServiceFactory;
_engineEnabledCheckerFactory = engineEnabledCheckerFactory;
_eventTriggerScheduleSetServiceFactory = eventTriggerScheduleSetServiceFactory;
_eventTriggerActionResultServiceFactory = eventTriggerActionResultServiceFactory;
_workflowExceptionHandlerFactory = workflowExceptionHandlerFactory;
}

/// <inheritdoc />
public IQueueProcessor Create()
{
return new QueueProcessor(
_qeueuedEventServiceFactory.Create(),
_loggerFactory.Create(),
_eventTriggerActionGroupLogServiceFactory.Create(),
_exceptionLogServiceFactory.Create(),
_eventTriggerServiceFactory.Create(),
_conditionServiceFactory.Create(),
_eventTriggerActionServiceFactory.Create(),
_engineEnabledCheckerFactory.Create(),
_eventTriggerScheduleSetServiceFactory.Create(),
_eventTriggerActionResultServiceFactory.Create(),
_workflowExceptionHandlerFactory.Create());
}
}

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

最佳答案

Does this mean I need ~60+ abstract factories in order to instantiate my IQueueProcessor in a worker thread?

最坏的情况下,可能需要这样做。当所有依赖项都必须具有 Transient 生命周期时,就会发生这种情况 - 例如,当它们不是线程安全的时。

然而,在最佳情况中,所有这些依赖项都可以具有单例生命周期,这可能适用于线程安全的依赖项。在那种情况下,不需要内部工厂:

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 依赖项(这需要工厂)和一些单例依赖项。

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

此外,您不必为每个依赖项定义接口(interface),但可以考虑使用通用接口(interface),例如:

public interface IFactory<T>
{
T Create();
}

同样,一些 DI 容器支持这样的工厂。您也可以考虑完全放弃接口(interface),只使用像 Func<T> 这样的委托(delegate)。 .

除非情况特殊,否则我不推荐DI Container,而是赞同Pure DI .当您使用 DI 容器时,您会失去编译时安全性,我倾向于认为这是不值得的权衡;毕竟,编程的瓶颈很少是你的打字速度。

关于c# - 使用依赖注入(inject)在工作线程中实例化对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50137520/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com