using System.Diagnostics.CodeAnalysis; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using OpenHarbor.JwtTokenManager.Abstractions; namespace OpenHarbor.JwtTokenManager; public static class ServiceCollectionExtensions { private static bool _defaultRegistered = false; [RequiresDynamicCode("Not AoT safe signature. Will add one in the future.")] public static IServiceCollection AddJwtTokenManager( this IServiceCollection services, IConfiguration configuration, string sectionName, string? name = null, Action? configureBuilderOptions = null) { if (configuration == null) throw new ArgumentNullException(nameof(configuration)); if (string.IsNullOrWhiteSpace(sectionName)) throw new ArgumentException("Section name must be provided.", nameof(sectionName)); name ??= sectionName; services.Configure(name, configuration.GetSection(sectionName)); var builderOptions = new JwtTokenManagerBuilderOptions(); configureBuilderOptions?.Invoke(builderOptions); services.AddKeyedSingleton(name, (provider, key) => { var optionsMonitor = provider.GetRequiredService>(); var options = optionsMonitor.Get(name); builderOptions.AdditionalConfiguration?.Invoke(options); var cacheOptions = new JwtTokenManagerCacheOptions(); builderOptions.CacheOptions?.Invoke(cacheOptions); var memoryCache = builderOptions.CacheFactory?.Invoke(provider) ?? provider.GetService(); var httpClientFactory = provider.GetRequiredService(); var logger = provider.GetService>(); return new JwtTokenManagerService(options, httpClientFactory, logger, memoryCache, cacheOptions); }); if (!_defaultRegistered) { services.AddSingleton(sp => sp.GetRequiredKeyedService(name)); _defaultRegistered = true; } return services; } [RequiresDynamicCode("Not AoT safe signature. Will add one in the future.")] public static IServiceCollection AddJwtTokenManager( this IServiceCollection services, IConfiguration configuration, string sectionName, Action? configureBuilderOptions = null) { return AddJwtTokenManager(services, configuration, sectionName, null, configureBuilderOptions); } }