using PostFundManagement.Application.Abstractions; using PostFundManagement.Application.Abstractions.Services; using PostFundManagement.Application.Interceptors; using PostFundManagement.Application.Services.Communications; using PostFundManagement.Application.Services.Evidence; using PostFundManagement.Application.Services.Execution; using PostFundManagement.Application.Services.Governance; using PostFundManagement.Application.Services.Grants; using PostFundManagement.Application.Services.Projects; using PostFundManagement.Application.Services.Shared; using PostFundManagement.Application.Services.Users; using PostFundManagement.Domain.Abstractions; namespace PostFundManagement.Application.Extensions; public static class Services { public static IServiceCollection AddLoggedCachedServiceScoped(this IServiceCollection services) where TInterface : class where TImplementation : class, TInterface where TCacheDecorator : class, TInterface { services.AddScoped(); services.AddScoped(); services.AddScoped(sp => { var proxyGenerator = sp.GetRequiredService(); var loggingInterceptor = sp.GetRequiredService(); var actual = sp.GetRequiredService(); var cached = ActivatorUtilities.CreateInstance(sp, actual); return proxyGenerator.CreateInterfaceProxyWithTarget(cached, loggingInterceptor.ToInterceptor()); }); return services; } public static IServiceCollection AddLoggedAuditedCachedServiceScoped(this IServiceCollection services) where TInterface : class where TImplementation : class, TInterface where TCacheDecorator : class, TInterface { services.AddScoped(); services.AddScoped(); services.AddScoped(sp => { var proxyGenerator = sp.GetRequiredService(); var auditInterceptor = sp.GetRequiredService(); var loggingInterceptor = sp.GetRequiredService(); var actual = sp.GetRequiredService(); var cached = ActivatorUtilities.CreateInstance(sp, actual); return proxyGenerator.CreateInterfaceProxyWithTarget(cached, loggingInterceptor.ToInterceptor(), auditInterceptor.ToInterceptor()); }); return services; } public static IServiceCollection AddRegisterServicesWithCaching(this IServiceCollection services, IConfiguration configuration) { services.AddScoped(); services.AddScoped(); services.AddSingleton(); services.AddLoggedAuditedCachedServiceScoped(); services.AddLoggedAuditedCachedServiceScoped(); services.AddLoggedAuditedCachedServiceScoped(); services.AddLoggedAuditedCachedServiceScoped(); services.AddLoggedAuditedCachedServiceScoped(); services.AddLoggedAuditedCachedServiceScoped(); services.AddLoggedAuditedCachedServiceScoped(); services.AddLoggedCachedServiceScoped(); services.AddStackExchangeRedisCache(options => { options.Configuration = configuration.GetConnectionString("Redis"); options.InstanceName = "PFM-API_"; }); services.AddHybridCache(options => options.DefaultEntryOptions = new HybridCacheEntryOptions { Expiration = TimeSpan.FromMinutes(2), LocalCacheExpiration = TimeSpan.FromMinutes(30) }); return services; } public static IServiceCollection AddSharedServices(this IServiceCollection services) { var serviceType = typeof(IService); var sharedImplementations = typeof(IApplication).Assembly.GetTypes() .Where(t => serviceType.IsAssignableFrom(t) && t.IsClass && !t.IsAbstract); foreach (var sharedImplementation in sharedImplementations) services.AddScoped(sharedImplementation); return services; } }