using Deal.Modules.Settings.Application.Abstractions; using Deal.Modules.Settings.Application.Models; using Deal.Modules.Settings.Application.Registrars; using Deal.Modules.Settings.Application.Services; using Microsoft.Extensions.DependencyInjection; using Deal.Modules.Discovery.Application.Abstractions; using Deal.Modules.Discovery.Application.Exceptions; using Deal.Modules.Discovery.Application.Extensions; using Deal.Modules.Discovery.Application.Models; using Deal.Modules.Discovery.Application.Services; namespace Deal.Modules.Discovery.Application.Registrars; /// /// DI-регистрация модуля Discovery. Паттерн «port & adapter» (Ruling 9, план Task 17). /// /// /// Регистрируются только сервисы модуля. Порт-адаптер IDiscoveryStore → DiscoveryStore реализован в /// Deal.Infrastructure и регистрируется там (AddDealPersistence) — модуль не знает про EF. Зависимости модуля — /// Deal.Modules.Settings (порт ISettingsStore: discJoinLimit/discEvalThreshold/discEvalSample) и Deal.Contracts; /// реверс-зависимостей нет (Global Constraints). Вызывается из Program.cs Deal.Api (AddDiscoveryModule, /// план Task 19 — эндпоинты; воркер Task 18 добавляет свои сервисы в тот же регистратор). /// public static class DiscoveryModuleRegistrar { /// /// Регистрирует сервисы модуля Discovery в контейнере. /// /// Коллекция сервисов. /// Коллекция сервисов для цепочки вызовов. /// /// Все сервисы scoped: их зависимости (IDiscoveryStore → TenantDbContext схемы тенанта, ISettingsStore) /// живут в рамках tenant-запроса/tenant-скоупа воркера (эталон TelegramModuleRegistrar). /// public static IServiceCollection AddDiscoveryModule(this IServiceCollection services) { services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); // Task 18 (воркер/оценка/бан-гард): DiscoveryWorkerService разрешается в tenant-скоупе цикла // (DiscoveryWorkerScheduler); IDiscoverySearchErrorCounter — singleton (счётчик ошибок ключей живёт // дольше scoped-воркера, как глобальный dict прототипа). DiscoveryBanGuard регистрируется фабрикой, // чтобы не резолвить опциональный параметр utcNow (дефолт — DateTimeOffset.UtcNow). services.AddSingleton(); services.AddSingleton(sp => sp.GetRequiredService()); services.AddScoped(); services.AddScoped(); services.AddScoped(sp => new DiscoveryBanGuard( sp.GetRequiredService(), sp.GetRequiredService())); services.AddScoped(); return services; } }