using System.Diagnostics.CodeAnalysis; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using PoweredSoft.Data.Core; using PoweredSoft.DynamicQuery; using PoweredSoft.DynamicQuery.Core; using Svrnty.CQRS.Abstractions; using Svrnty.CQRS.Abstractions.Discovery; using Svrnty.CQRS.DynamicQuery.Abstractions; using Svrnty.CQRS.DynamicQuery.Discover; namespace Svrnty.CQRS.DynamicQuery; public static class ServiceCollectionExtensions { /// /// Registers core DynamicQuery services with in-memory async queryable. /// For EF Core projects, chain with .UseEntityFramework(). /// /// The service collection. /// A builder for further configuration. public static DynamicQueryServicesBuilder AddDynamicQueryServices(this IServiceCollection services) { services.TryAddTransient(); services.TryAddTransient(); return new DynamicQueryServicesBuilder(services); } public static IServiceCollection AddDynamicQuery(this IServiceCollection services, string name = null) where TSourceAndDestination : class => AddDynamicQuery(services, name: name); public static IServiceCollection AddDynamicQuery(this IServiceCollection services, string name = null) where TSource : class where TDestination : class { // add query handler. services.AddTransient, IQueryExecutionResult>, DynamicQueryHandler>(); // add for discovery purposes. var queryType = typeof(IDynamicQuery); var resultType = typeof(IQueryExecutionResult); var serviceType = typeof(DynamicQueryHandler); var queryMeta = new DynamicQueryMeta(queryType, serviceType, resultType) { OverridableName = name }; services.AddSingleton(queryMeta); return services; } public static IServiceCollection AddDynamicQueryWithProvider(this IServiceCollection services, string name = null) where TQueryableProvider : class, IQueryableProvider where TSource : class { services.AddTransient, TQueryableProvider>() .AddDynamicQuery(name: name); return services; } public static IServiceCollection AddDynamicQueryWithParamsAndProvider(this IServiceCollection services, string name = null) where TQueryableProvider : class, IQueryableProvider where TParams : class where TSource : class { services.AddTransient, TQueryableProvider>() .AddDynamicQueryWithParams(name: name); return services; } /// /// Registers a custom queryable provider override for the specified source type. /// Use this for DTOs that require custom projection from entities. /// /// The DTO/Item type returned by the queryable. /// The provider implementation type. /// The service collection. /// The service collection for chaining. public static IServiceCollection AddQueryableProviderOverride(this IServiceCollection services) where TSource : class where TProvider : class, IQueryableProviderOverride { services.AddTransient, TProvider>(); return services; } public static IServiceCollection AddDynamicQueryWithParams(this IServiceCollection services, string name = null) where TSourceAndDestination : class where TParams : class => AddDynamicQueryWithParams(services, name: name); public static IServiceCollection AddDynamicQueryWithParams(this IServiceCollection services, string name = null) where TSource : class where TDestination : class where TParams : class { // add query handler. services.AddTransient, IQueryExecutionResult>, DynamicQueryHandler>(); // add for discovery purposes. var queryType = typeof(IDynamicQuery); var resultType = typeof(IQueryExecutionResult); var serviceType = typeof(DynamicQueryHandler); var queryMeta = new DynamicQueryMeta(queryType, serviceType, resultType) { // params type. ParamsType = typeof(TParams), OverridableName = name }; services.AddSingleton(queryMeta); return services; } public static IServiceCollection AddAlterQueryable(this IServiceCollection services) where TService : class, IAlterQueryableService { return services.AddTransient, TService>(); } public static IServiceCollection AddAlterQueryable(this IServiceCollection services) where TService : class, IAlterQueryableService { return services.AddTransient, TService>(); } public static IServiceCollection AddAlterQueryableWithParams (this IServiceCollection services) where TParams : class where TService : class, IAlterQueryableService { return services.AddTransient, TService>(); } public static IServiceCollection AddAlterQueryableWithParams (this IServiceCollection services) where TParams : class where TService : class, IAlterQueryableService { return services.AddTransient, TService>(); } public static IServiceCollection AddDynamicQueryInterceptor(this IServiceCollection services) where TInterceptor : class, IQueryInterceptor { services.TryAddTransient(); return services.AddSingleton>( new DynamicQueryInterceptorProvider(typeof(TInterceptor))); } public static IServiceCollection AddDynamicQueryInterceptors(this IServiceCollection services) where T1 : class, IQueryInterceptor where T2 : class, IQueryInterceptor { services.TryAddTransient(); services.TryAddTransient(); return services.AddSingleton>( new DynamicQueryInterceptorProvider(typeof(T1), typeof(T2))); } public static IServiceCollection AddDynamicQueryInterceptors(this IServiceCollection services) where T1 : class, IQueryInterceptor where T2 : class, IQueryInterceptor where T3 : class, IQueryInterceptor { services.TryAddTransient(); services.TryAddTransient(); services.TryAddTransient(); return services.AddSingleton>( new DynamicQueryInterceptorProvider(typeof(T1), typeof(T2), typeof(T3))); } public static IServiceCollection AddDynamicQueryInterceptors(this IServiceCollection services) where T1 : class, IQueryInterceptor where T2 : class, IQueryInterceptor where T3 : class, IQueryInterceptor where T4 : class, IQueryInterceptor { services.TryAddTransient(); services.TryAddTransient(); services.TryAddTransient(); services.TryAddTransient(); return services.AddSingleton>( new DynamicQueryInterceptorProvider(typeof(T1), typeof(T2), typeof(T3), typeof(T4))); } public static IServiceCollection AddDynamicQueryInterceptors(this IServiceCollection services) where T1 : class, IQueryInterceptor where T2 : class, IQueryInterceptor where T3 : class, IQueryInterceptor where T4 : class, IQueryInterceptor where T5 : class, IQueryInterceptor { services.TryAddTransient(); services.TryAddTransient(); services.TryAddTransient(); services.TryAddTransient(); services.TryAddTransient(); return services.AddSingleton>( new DynamicQueryInterceptorProvider(typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5))); } }