My objective is to run a never ending process in a parallel thread. The problem is, I cannot just instantiate my worker service in the new Thread, because I am using DI in my application.
Based on my research here on SO, I have noticed many people are suggesting that Abstract Factories need to be injected into the thread to dynamically instantiate a thread-safe object in a parallel thread. 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();
}
}
The Abstract Factory for IQueueProcessorFactory
looks like this:
/// <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();
}
Now, my main problem is, the concrete QueueProcessor
that implements IQueueProcessor
has 11 dependencies (I'm aware of the SRP code smell), and each dependency has 5-6 dependencies itself.
/// <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());
}
}
Does this mean I need ~60+ abstract factories in order to instantiate my IQueueProcessor
in a worker thread? This sounds like a nightmare! Is there a better way or a more efficient way to achieve this?