| | | 1 | | using Elsa.UserTasks.Contracts; |
| | | 2 | | using Elsa.UserTasks.Options; |
| | | 3 | | using Elsa.UserTasks.Repositories; |
| | | 4 | | using Elsa.UserTasks.Services; |
| | | 5 | | using Elsa.Mediator.Extensions; |
| | | 6 | | using Microsoft.Extensions.DependencyInjection; |
| | | 7 | | using Microsoft.Extensions.DependencyInjection.Extensions; |
| | | 8 | | |
| | | 9 | | namespace Elsa.UserTasks.Extensions; |
| | | 10 | | |
| | | 11 | | public static class ServiceCollectionExtensions |
| | | 12 | | { |
| | | 13 | | public static IServiceCollection AddUserTasksServices(this IServiceCollection services, Action<UserTasksOptions>? co |
| | | 14 | | { |
| | 0 | 15 | | if (configure != null) |
| | 0 | 16 | | services.Configure(configure); |
| | 0 | 17 | | services.AddOptions<UserTasksOptions>(); |
| | 0 | 18 | | services.TryAddSingleton<IUserTaskIdentityResolver, DefaultClaimsIdentityResolver>(); |
| | 0 | 19 | | services.TryAddSingleton<IUserTaskAccessPolicy, DefaultUserTaskAccessPolicy>(); |
| | 0 | 20 | | services.TryAddSingleton<IUserTaskParticipantDirectory, EmptyUserTaskParticipantDirectory>(); |
| | | 21 | | |
| | | 22 | | // The in-memory defaults below hold process state, so they stay singletons. A persistence provider |
| | | 23 | | // replaces them with scoped, store-backed implementations. |
| | 0 | 24 | | services.TryAddSingleton<IUserTaskRepository, InMemoryUserTaskRepository>(); |
| | 0 | 25 | | services.TryAddSingleton<IUserTaskGuestSessionIssuer, InMemoryUserTaskGuestSessionIssuer>(); |
| | 0 | 26 | | services.TryAddSingleton<IUserTaskInvitationRateLimiter, SlidingWindowUserTaskInvitationRateLimiter>(); |
| | 0 | 27 | | services.TryAddSingleton<IUserTaskInvitationOutbox, InMemoryUserTaskInvitationOutbox>(); |
| | 0 | 28 | | services.TryAddSingleton<IUserTaskInvitationDispatcher, NullUserTaskInvitationDispatcher>(); |
| | 0 | 29 | | services.TryAddSingleton<IUserTaskInvitationVerifier, DefaultUserTaskInvitationVerifier>(); |
| | 0 | 30 | | services.TryAddSingleton<IUserTaskNotificationSink, DefaultUserTaskNotificationSink>(); |
| | 0 | 31 | | services.TryAddSingleton<IUserTaskWorkflowResumer, DefaultUserTaskWorkflowResumer>(); |
| | | 32 | | |
| | | 33 | | // Everything that consumes a repository is scoped: a provider-backed repository resolves a DbContext |
| | | 34 | | // from the ambient scope, and a singleton consumer would capture it. |
| | 0 | 35 | | services.TryAddScoped<IUserTaskManager, DefaultUserTaskManager>(); |
| | 0 | 36 | | services.TryAddScoped<IUserTaskProjectionService, DefaultUserTaskProjectionService>(); |
| | 0 | 37 | | services.TryAddScoped<IUserTaskDueService, DefaultUserTaskDueService>(); |
| | 0 | 38 | | services.TryAddScoped<IUserTaskReconciler, DefaultUserTaskReconciler>(); |
| | 0 | 39 | | services.TryAddScoped<IUserTaskInvitationService, DefaultUserTaskInvitationService>(); |
| | 0 | 40 | | services.TryAddScoped<UserTaskGuestActorResolver>(); |
| | 0 | 41 | | services.AddNotificationHandler<Handlers.UserTaskBookmarkPersistedHandler>(); |
| | | 42 | | |
| | | 43 | | // Hosted workers own the periodic side of the module: due/timeout sweeps, projection reconciliation, |
| | | 44 | | // and draining the encrypted invitation outbox. |
| | 0 | 45 | | services.AddHostedService<HostedServices.UserTaskDueWorker>(); |
| | 0 | 46 | | services.AddHostedService<HostedServices.UserTaskReconciliationWorker>(); |
| | 0 | 47 | | services.AddHostedService<HostedServices.UserTaskInvitationDeliveryWorker>(); |
| | 0 | 48 | | return services; |
| | | 49 | | } |
| | | 50 | | } |