using DigitalData.EmailProfilerDispatcher; using DigitalData.UserManager.DependencyInjection; using EnvelopeGenerator.Application; using EnvelopeGenerator.Infrastructure; using Microsoft.Extensions.Caching.SqlServer; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using static EnvelopeGenerator.Infrastructure.DependencyInjection; namespace EnvelopeGenerator.DependencyInjection; public static class DependencyInjection { public static IServiceCollection AddEnvelopeGenerator(this IServiceCollection services, Action options) { var egConfig = new EGConfiguration(); options.Invoke(egConfig); egConfig.EnsureAllServicesConfigured(); egConfig.RegisterAll(services); // Add envelope generator services #pragma warning disable CS0618 services.AddUserManager(); #pragma warning restore CS0618 services.AddDispatcher(); return services; } public record EGConfiguration { internal readonly Queue> _serviceRegs = new(); internal void RegisterAll(IServiceCollection services) { while (_serviceRegs.Count > 0) _serviceRegs.Dequeue().Invoke(services); } // TODO: update to use attributes and reflections instead of _addingStatus-dictionary private readonly Dictionary _addingStatus = new () { { nameof(AddLocalization), false }, { nameof(AddDistributedSqlServerCache), false }, { nameof(AddInfrastructure), false }, { nameof(AddServices), false }, }; public EGConfiguration AddLocalization(Action? customLocalizationOptions = null) { _serviceRegs.Enqueue(customLocalizationOptions ?? (s => s.AddLocalization())); _addingStatus[nameof(AddLocalization)] = true; return this; } public EGConfiguration AddDistributedSqlServerCache(Action setupAction) { _serviceRegs.Enqueue(s => s.AddDistributedSqlServerCache(setupAction)); _addingStatus[nameof(AddDistributedSqlServerCache)] = true; return this; } public EGConfiguration AddInfrastructure(Action options) { #pragma warning disable CS0618 _serviceRegs.Enqueue(s => s.AddEGInfrastructureServices(options)); #pragma warning restore CS0618 _addingStatus[nameof(AddInfrastructure)] = true; return this; } public EGConfiguration AddServices(IConfiguration config, bool usePdfBurner = false) { #pragma warning disable CS0618 _serviceRegs.Enqueue(s => s.AddEnvelopeGeneratorServices(config, usePdfBurner)); #pragma warning restore CS0618 _addingStatus[nameof(AddServices)] = true; return this; } internal void EnsureAllServicesConfigured() { var missingServices = _addingStatus .Where(kv => !kv.Value) .Select(kv => kv.Key) .ToList(); if (missingServices.Count > 0) { var missingList = string.Join(", ", missingServices); throw new InvalidOperationException( $"Service configuration incomplete. The following required service methods were not called: {missingList}. " + "Please ensure all necessary configuration methods are invoked before building the application."); } } } }