using System.Reflection; using FluentValidation; using LiteCqrs.Behaviors; using LiteCqrs.DependencyInjection; using Microsoft.Extensions.DependencyInjection; using TeleWave.Application.Common.Behaviors; namespace TeleWave.Application; public static class DependencyInjection { public static IServiceCollection AddApplication(this IServiceCollection services) { var assembly = typeof(DependencyInjection).Assembly; services.AddLiteCqrs(cqrs => { cqrs.RegisterServicesFromAssembly(assembly); cqrs.Lifetime = ServiceLifetime.Scoped; // Порядок важен: Logging (внешний) -> Validation -> UnitOfWork (ближе всего к хендлеру). cqrs.AddOpenBehavior(typeof(LoggingBehavior<,>)); cqrs.AddOpenBehavior(typeof(ValidationBehavior<,>)); cqrs.AddOpenBehavior(typeof(UnitOfWorkBehavior<,>)); }); RegisterClosedGeneric(services, assembly, typeof(IValidator<>)); return services; } private static void RegisterClosedGeneric(IServiceCollection services, Assembly assembly, Type openInterface) { var implementations = assembly.GetTypes() .Where(t => t is { IsClass: true, IsAbstract: false }) .SelectMany(t => t.GetInterfaces() .Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == openInterface) .Select(i => (Service: i, Implementation: t))); foreach (var (service, implementation) in implementations) services.AddScoped(service, implementation); } }