using FluentValidation; using MediatR; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using System.Reflection; using ZeroFramework.DeviceCenter.Application.Behaviors; using ZeroFramework.DeviceCenter.Application.Infrastructure; using ZeroFramework.DeviceCenter.Application.Models.Monitoring; using ZeroFramework.DeviceCenter.Application.Models.Projects; using ZeroFramework.DeviceCenter.Application.Queries.Factories; using ZeroFramework.DeviceCenter.Application.Queries.Monitoring; using ZeroFramework.DeviceCenter.Application.Queries.Ordering; using ZeroFramework.DeviceCenter.Application.Services.Devices; using ZeroFramework.DeviceCenter.Application.Services.Generics; using ZeroFramework.DeviceCenter.Application.Services.Measurements; using ZeroFramework.DeviceCenter.Application.Services.Ordering; using ZeroFramework.DeviceCenter.Application.Services.Permissions; using ZeroFramework.DeviceCenter.Application.Services.Products; using ZeroFramework.DeviceCenter.Application.Services.Projects; using ZeroFramework.DeviceCenter.Application.Services.ResourceGroups; using ZeroFramework.DeviceCenter.Application.Services.Tenants; using ZeroFramework.DeviceCenter.Domain.Aggregates.MonitoringAggregate; using ZeroFramework.DeviceCenter.Domain.Repositories; using ZeroFramework.DeviceCenter.Infrastructure.Constants; using ZeroFramework.DeviceCenter.Infrastructure.Idempotency; using ZeroFramework.EventBus; using ZeroFramework.EventBus.Abstractions; using ZeroFramework.EventBus.RabbitMQ; namespace ZeroFramework.DeviceCenter.Application { public static class DependencyRegistrar { public static IServiceCollection AddApplicationLayer(this IServiceCollection services, IConfiguration configuration) { services.AddDomainEvents(); services.AddEventBus(configuration).AddIntegrationEvents(); services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies()); services.AddQueries(configuration); services.AddApplicationServices(); services.AddAuthorization(); return services; } private static IServiceCollection AddDomainEvents(this IServiceCollection services) { // Registers handlers and mediator types from the specified assemblies services.AddTransient(typeof(IPipelineBehavior<,>), typeof(LoggingBehavior<,>)); services.AddTransient(typeof(IPipelineBehavior<,>), typeof(ValidatorBehavior<,>)); services.AddMediatR(config => config.RegisterServicesFromAssemblies(AppDomain.CurrentDomain.GetAssemblies())); ValidatorOptions.Global.LanguageManager = new Extensions.Validators.CustomLanguageManager(); services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly()); services.AddTransient(); return services; } private static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration) { services.AddSingleton(); IConfigurationSection configurationSection = configuration.GetSection("EventBus"); int retryCount = 5; if (!string.IsNullOrEmpty(configurationSection["EventBusRetryCount"])) { retryCount = int.Parse(configurationSection["EventBusRetryCount"]!); } services.AddSingleton(sp => { var logger = sp.GetRequiredService>(); var factory = new RabbitMQ.Client.ConnectionFactory() { HostName = configurationSection["EventBusConnection"], DispatchConsumersAsync = true }; if (!string.IsNullOrEmpty(configurationSection["EventBusUserName"])) { factory.UserName = configurationSection["EventBusUserName"]; } if (!string.IsNullOrEmpty(configurationSection["EventBusPassword"])) { factory.Password = configurationSection["EventBusPassword"]; } return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); }); services.AddSingleton(sp => { var rabbitMQPersistentConnection = sp.GetRequiredService(); var logger = sp.GetRequiredService>(); var eventBusSubcriptionsManager = sp.GetRequiredService(); string queueName = configurationSection["SubscriptionClientName"]!; return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, sp, eventBusSubcriptionsManager, queueName, retryCount); }); return services; } private static IServiceCollection AddIntegrationEvents(this IServiceCollection services) { var exportedTypes = Assembly.GetExecutingAssembly().ExportedTypes; var integrationEventHandlers = exportedTypes.Where(t => t.IsAssignableTo(typeof(IIntegrationEventHandler)) && t.IsClass); integrationEventHandlers.ToList().ForEach(t => services.AddTransient(typeof(IIntegrationEventHandler), t)); services.AddTransient(); return services; } private static IServiceCollection AddQueries(this IServiceCollection services, IConfiguration configuration) { services.AddSingleton(); string connectionString = configuration.GetConnectionString(DbConstants.DefaultConnectionStringName)!; services.AddTransient(o => new OrderQueries(connectionString)); services.AddTransient(); return services; } private static IServiceCollection AddApplicationServices(this IServiceCollection services) { var exportedTypes = Assembly.GetExecutingAssembly().ExportedTypes; var dataSeedProviders = exportedTypes.Where(t => t.IsAssignableTo(typeof(IDataSeedProvider)) && t.IsClass); dataSeedProviders.ToList().ForEach(t => services.AddTransient(typeof(IDataSeedProvider), t)); services.AddTransient(typeof(ICrudApplicationService), typeof(ProjectApplicationService)); services.AddTransient(typeof(ICrudApplicationService), typeof(CrudApplicationService)); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); return services; } private static IServiceCollection AddAuthorization(this IServiceCollection services) { services.AddDistributedMemoryCache().AddTransient(); services.AddTransient(); var exportedTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.ExportedTypes).Where(t => t.IsClass); var permissionDefinitionProviders = exportedTypes.Where(t => t.IsAssignableTo(typeof(IPermissionDefinitionProvider))); permissionDefinitionProviders.ToList().ForEach(t => services.AddSingleton(typeof(IPermissionDefinitionProvider), t)); var permissionValueProviders = exportedTypes.Where(t => t.IsAssignableTo(typeof(IPermissionValueProvider))); permissionValueProviders.ToList().ForEach(t => services.AddTransient(typeof(IPermissionValueProvider), t)); return services; } } }