From 480b726c9d79671b5d494fdfb272c7f38aec27fe Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Fri, 5 Jan 2024 12:13:44 +0100 Subject: [PATCH] Refactor service dependencies in BackgroundTaskDispatcher and LocalBackgroundActivityScheduler (#4753) Removed explicit dependency resolution from the constructors of BackgroundTaskDispatcher and LocalBackgroundActivityScheduler classes, and used IServiceScopeFactory to resolve dependencies inside methods instead. Updated their lifetimes from Scoped to Singleton in the DI container in WorkflowRuntimeFeature. The DI container now manages the lifetime scope of these services, promoting better separation of responsibilities and improved testability. --- .../Features/WorkflowRuntimeFeature.cs | 4 ++-- .../Services/BackgroundTaskDispatcher.cs | 17 +++++++------- .../LocalBackgroundActivityScheduler.cs | 23 ++++++------------- 3 files changed, 17 insertions(+), 27 deletions(-) diff --git a/src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs b/src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs index 41c867f95f..1f2ac45b30 100644 --- a/src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs +++ b/src/modules/Elsa.Workflows.Runtime/Features/WorkflowRuntimeFeature.cs @@ -157,8 +157,8 @@ public override void Apply() .AddScoped(WorkflowExecutionLogStore) .AddScoped(ActivityExecutionLogStore) .AddScoped(WorkflowInboxStore) - .AddScoped(RunTaskDispatcher) - .AddScoped(BackgroundActivityScheduler) + .AddSingleton(RunTaskDispatcher) + .AddSingleton(BackgroundActivityScheduler) .AddScoped() .AddScoped() .AddScoped() diff --git a/src/modules/Elsa.Workflows.Runtime/Services/BackgroundTaskDispatcher.cs b/src/modules/Elsa.Workflows.Runtime/Services/BackgroundTaskDispatcher.cs index 55f8870a2c..a73edb92cc 100644 --- a/src/modules/Elsa.Workflows.Runtime/Services/BackgroundTaskDispatcher.cs +++ b/src/modules/Elsa.Workflows.Runtime/Services/BackgroundTaskDispatcher.cs @@ -2,21 +2,20 @@ using Elsa.Mediator.Contracts; using Elsa.Workflows.Runtime.Contracts; using Elsa.Workflows.Runtime.Notifications; +using Microsoft.Extensions.DependencyInjection; namespace Elsa.Workflows.Runtime.Services; /// /// Relies on the to publish the received request as a domain event from a background worker. /// -public class BackgroundTaskDispatcher : ITaskDispatcher +public class BackgroundTaskDispatcher(IServiceScopeFactory scopeFactory) : ITaskDispatcher { - private readonly INotificationSender _eventPublisher; - - /// - /// Constructor. - /// - public BackgroundTaskDispatcher(INotificationSender eventPublisher) => _eventPublisher = eventPublisher; - /// - public async Task DispatchAsync(RunTaskRequest request, CancellationToken cancellationToken = default) => await _eventPublisher.SendAsync(request, NotificationStrategy.Background, cancellationToken); + public async Task DispatchAsync(RunTaskRequest request, CancellationToken cancellationToken = default) + { + using var scope = scopeFactory.CreateScope(); + var notificationSender = scope.ServiceProvider.GetRequiredService(); + await notificationSender.SendAsync(request, NotificationStrategy.Background, cancellationToken); + } } \ No newline at end of file diff --git a/src/modules/Elsa.Workflows.Runtime/Services/LocalBackgroundActivityScheduler.cs b/src/modules/Elsa.Workflows.Runtime/Services/LocalBackgroundActivityScheduler.cs index c00dc9face..7363771734 100644 --- a/src/modules/Elsa.Workflows.Runtime/Services/LocalBackgroundActivityScheduler.cs +++ b/src/modules/Elsa.Workflows.Runtime/Services/LocalBackgroundActivityScheduler.cs @@ -1,42 +1,33 @@ using Elsa.Mediator.Contracts; using Elsa.Workflows.Runtime.Contracts; using Elsa.Workflows.Runtime.Models; +using Microsoft.Extensions.DependencyInjection; namespace Elsa.Workflows.Runtime.Services; /// /// Invokes activities from a background worker within the context of its workflow instance using a local background worker. /// -public class LocalBackgroundActivityScheduler : IBackgroundActivityScheduler +public class LocalBackgroundActivityScheduler(IJobQueue jobQueue, IServiceScopeFactory scopeFactory) : IBackgroundActivityScheduler { - private readonly IJobQueue _jobQueue; - private readonly IBackgroundActivityInvoker _backgroundActivityInvoker; - - /// - /// Initializes a new instance of the class. - /// - public LocalBackgroundActivityScheduler(IJobQueue jobQueue, IBackgroundActivityInvoker backgroundActivityInvoker) - { - _jobQueue = jobQueue; - _backgroundActivityInvoker = backgroundActivityInvoker; - } - /// public Task ScheduleAsync(ScheduledBackgroundActivity scheduledBackgroundActivity, CancellationToken cancellationToken = default) { - var jobId = _jobQueue.Enqueue(async ct => await InvokeBackgroundActivity(scheduledBackgroundActivity, ct)); + var jobId = jobQueue.Enqueue(async ct => await InvokeBackgroundActivity(scheduledBackgroundActivity, ct)); return Task.FromResult(jobId); } /// public Task CancelAsync(string jobId, CancellationToken cancellationToken = default) { - _jobQueue.Cancel(jobId); + jobQueue.Cancel(jobId); return Task.CompletedTask; } private async Task InvokeBackgroundActivity(ScheduledBackgroundActivity scheduledBackgroundActivity, CancellationToken cancellationToken) { - await _backgroundActivityInvoker.ExecuteAsync(scheduledBackgroundActivity, cancellationToken); + using var scope = scopeFactory.CreateScope(); + var backgroundActivityInvoker = scope.ServiceProvider.GetRequiredService(); + await backgroundActivityInvoker.ExecuteAsync(scheduledBackgroundActivity, cancellationToken); } } \ No newline at end of file