Files
Deal/src/core/Deal.Modules.Discovery/Application/Registrars/DiscoveryModuleRegistrar.cs
T
Rustam Khalimov cd0b3b606b Разбить модули Deal.Modules.* по назначению
Application проектов Discovery, Kanban, Pipeline, Settings, Tenants
разделён на Abstractions/Exceptions/Extensions/Models/Registrars/Services;
namespace приведён к путям, using потребителей мигрированы и
дедуплицированы (169 файлов), cref/FQN обновлены.
2026-09-11 13:18:14 +03:00

58 lines
3.6 KiB
C#

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;
/// <summary>
/// DI-регистрация модуля Discovery. Паттерн «port &amp; adapter» (Ruling 9, план Task 17).
/// </summary>
/// <remarks>
/// Регистрируются только сервисы модуля. Порт-адаптер <c>IDiscoveryStore</c> → 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 добавляет свои сервисы в тот же регистратор).
/// </remarks>
public static class DiscoveryModuleRegistrar
{
/// <summary>
/// Регистрирует сервисы модуля Discovery в контейнере.
/// </summary>
/// <param name="services">Коллекция сервисов.</param>
/// <returns>Коллекция сервисов для цепочки вызовов.</returns>
/// <remarks>
/// Все сервисы scoped: их зависимости (IDiscoveryStore → TenantDbContext схемы тенанта, ISettingsStore)
/// живут в рамках tenant-запроса/tenant-скоупа воркера (эталон TelegramModuleRegistrar).
/// </remarks>
public static IServiceCollection AddDiscoveryModule(this IServiceCollection services)
{
services.AddScoped<DiscoveryPlanGuard>();
services.AddScoped<DiscoveryTasksService>();
services.AddScoped<DiscoveryCandidatesService>();
services.AddScoped<DiscoveryBlacklistService>();
services.AddScoped<DiscoveryLogService>();
// Task 18 (воркер/оценка/бан-гард): DiscoveryWorkerService разрешается в tenant-скоупе цикла
// (DiscoveryWorkerScheduler); IDiscoverySearchErrorCounter — singleton (счётчик ошибок ключей живёт
// дольше scoped-воркера, как глобальный dict прототипа). DiscoveryBanGuard регистрируется фабрикой,
// чтобы не резолвить опциональный параметр utcNow (дефолт — DateTimeOffset.UtcNow).
services.AddSingleton<DiscoverySearchErrorCounter>();
services.AddSingleton<IDiscoverySearchErrorCounter>(sp => sp.GetRequiredService<DiscoverySearchErrorCounter>());
services.AddScoped<DiscoveryEvaluator>();
services.AddScoped<IDiscoveryPacer, DiscoveryPacer>();
services.AddScoped(sp => new DiscoveryBanGuard(
sp.GetRequiredService<IDiscoveryStore>(),
sp.GetRequiredService<ISettingsStore>()));
services.AddScoped<DiscoveryWorkerService>();
return services;
}
}