Создание сервисов с порт-интерфейсом перенесено в IXxxFactory: шифр секретов, хранилище лимитов, ИИ-классификатор, ИИ-инструменты, файловое хранилище (Local/MinIO). Регистраторы и DiscoveryWorkerService больше не создают реализации напрямую. Добавлен тест FileStorageFactory.
157 lines
6.9 KiB
C#
157 lines
6.9 KiB
C#
using Deal.Contracts.Integrations.Abstractions;
|
|
using Deal.Infrastructure.Integrations.Abstractions;
|
|
using Deal.Infrastructure.Integrations.Models;
|
|
using Deal.Infrastructure.Integrations.Options;
|
|
using Deal.Infrastructure.Integrations.Services;
|
|
using Deal.Infrastructure.Integrations.Sources;
|
|
using Deal.Infrastructure.Persistence;
|
|
using Deal.Infrastructure.Persistence.Abstractions;
|
|
using Deal.Infrastructure.Persistence.Repositories;
|
|
using Deal.Infrastructure.Persistence.Services;
|
|
using Deal.Infrastructure.Security;
|
|
using Deal.Infrastructure.Security.Abstractions;
|
|
using Deal.Infrastructure.Security.Services;
|
|
using Deal.Infrastructure.Services;
|
|
using Deal.Infrastructure.Tenancy;
|
|
using Deal.Modules.Cards.Application.Abstractions;
|
|
using Deal.Modules.Cards.Application.Sources;
|
|
using Deal.Modules.Discovery.Application.Abstractions;
|
|
using Deal.Modules.Kanban.Application.Abstractions;
|
|
using Deal.Modules.Pipeline.Application.Abstractions;
|
|
using Deal.Modules.Settings.Application.Abstractions;
|
|
using Deal.Modules.Telegram.Application;
|
|
using Deal.Modules.Tenants.Application.Abstractions;
|
|
using Deal.Modules.Tenants.Application.Models;
|
|
using Deal.SharedKernel.Tenants.Abstractions;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
namespace Deal.Infrastructure;
|
|
|
|
/// <summary>
|
|
/// DI-регистрация адаптеров персистентности Deal.Infrastructure.
|
|
/// </summary>
|
|
public static class ServiceCollectionExtensions
|
|
{
|
|
/// <summary>
|
|
/// Регистрирует EF-адаптеры портов модулей
|
|
/// </summary>
|
|
/// <param name="tenantLimitDefaults">Дефолт-бюджет лениво создаваемых строк tenant_limits. Передаётся из конфигурации/env DEAL_DEFAULT_AI_BUDGET в Program.cs.</param>
|
|
public static IServiceCollection AddDealPersistence(this IServiceCollection services, TokenLimitDefaults? tenantLimitDefaults = null)
|
|
{
|
|
services.AddScoped<IAuthStore, AuthStore>();
|
|
|
|
services.AddScoped<IOperatorAuthStore, OperatorAuthStore>();
|
|
services.AddScoped<ITenantRepository, TenantRepository>();
|
|
|
|
services.AddScoped<IAuditLogStore, AuditLogStore>();
|
|
|
|
services.AddScoped<ITokenUsageEventStore, TokenUsageEventStore>();
|
|
|
|
services.AddScoped<IInviteStore, InviteStore>();
|
|
|
|
services.AddSingleton(tenantLimitDefaults ?? TokenBudgetDefaults.Default);
|
|
services.AddScoped<ITenantLimitStoreFactory, TenantLimitStoreFactory>();
|
|
services.AddScoped<ITenantLimitStore>(provider => provider.GetRequiredService<ITenantLimitStoreFactory>().Create());
|
|
|
|
services.AddScoped<IRateLimitCounterStore, RateLimitCounterStore>();
|
|
|
|
services.AddScoped<ISettingsStore, SettingsStore>();
|
|
|
|
services.AddScoped<IGlobalSettingsStore, GlobalSettingsStore>();
|
|
|
|
services.AddScoped<ICardStore, KanbanStore>();
|
|
|
|
services.AddScoped<ISourceContentProvider, TelegramSourceContentProvider>();
|
|
|
|
services.AddScoped<IPipelineStore, PipelineStore>();
|
|
|
|
services.AddScoped<IMlLearningStore, MlLearningStore>();
|
|
|
|
services.AddScoped<ITelegramStore, TelegramStore>();
|
|
|
|
services.AddScoped<IDiscoveryStore, DiscoveryStore>();
|
|
|
|
services.AddScoped<ITenantProvisioner, TenantProvisioningService>();
|
|
|
|
services.AddScoped<TenantSchemaMigrationService>();
|
|
|
|
services.AddScoped<ICardMover, CardMover>();
|
|
return services;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Регистрирует адаптеры внешних интеграций
|
|
/// </summary>
|
|
/// <param name="mlOptions">Конфигурация секции <c>Services:Ml</c> — выбор реализации IMlClient.</param>
|
|
/// <param name="aiOptions">Конфигурация секции <c>Services:Ai</c> — выбор реализации IAiClassifier/IAiTools.</param>
|
|
/// <param name="telegramOptions">Конфигурация секции <c>Services:Telegram</c> — выбор реализации ITelegramGateway.</param>
|
|
public static IServiceCollection AddDealIntegrations(
|
|
this IServiceCollection services,
|
|
MlServiceOptions mlOptions,
|
|
AiServiceOptions aiOptions,
|
|
TelegramServiceOptions telegramOptions,
|
|
MtlsCertificates? mtlsCertificates = null)
|
|
{
|
|
services.AddScoped<TokenUsageRecorder>();
|
|
|
|
if (mlOptions.UseLocal)
|
|
{
|
|
services.AddScoped<IMlClient, LocalMlClient>();
|
|
}
|
|
else
|
|
{
|
|
services.AddSingleton(new MlGrpcConnection(mlOptions, mtlsCertificates));
|
|
services.AddSingleton<MlStatusCache>();
|
|
services.AddScoped<GrpcMlClient>();
|
|
services.AddScoped<IMlClient>(provider => provider.GetRequiredService<GrpcMlClient>());
|
|
services.AddScoped<IMlTrainClient>(provider => provider.GetRequiredService<GrpcMlClient>());
|
|
}
|
|
|
|
services.AddScoped<IColumnSuggester, LocalColumnSuggester>();
|
|
|
|
if (aiOptions.UseLocal)
|
|
{
|
|
services.AddScoped<IAiClassifier, LocalAiClassifier>();
|
|
services.AddScoped<IAiTools, LocalAiTools>();
|
|
}
|
|
else
|
|
{
|
|
services.AddSingleton(new AiGrpcConnection(aiOptions, mtlsCertificates));
|
|
services.AddScoped<AiProviderConfigBuilder>();
|
|
services.AddScoped<GrpcAiClassifier>();
|
|
services.AddScoped<LocalAiClassifier>();
|
|
services.AddScoped<IAiClassifierFactory, AiClassifierFactory>();
|
|
services.AddScoped<IAiClassifier>(provider => provider.GetRequiredService<IAiClassifierFactory>().Create());
|
|
services.AddScoped<GrpcAiTools>();
|
|
services.AddScoped<IAiToolsFactory, AiToolsFactory>();
|
|
services.AddScoped<IAiTools>(provider => provider.GetRequiredService<IAiToolsFactory>().Create());
|
|
}
|
|
|
|
if (telegramOptions.UseLocal)
|
|
{
|
|
services.AddSingleton<ITelegramGateway, LocalTelegramGateway>();
|
|
}
|
|
else
|
|
{
|
|
services.AddSingleton(new TelegramGrpcConnection(telegramOptions, mtlsCertificates));
|
|
services.AddScoped<GrpcTelegramClient>();
|
|
services.AddScoped<ITelegramGateway>(provider => provider.GetRequiredService<GrpcTelegramClient>());
|
|
}
|
|
|
|
return services;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Регистрирует сервисы шифрования секретов
|
|
/// </summary>
|
|
/// <param name="contentRootPath">ContentRoot приложения — каталог по умолчанию для файла-ключа data/encryption.key.</param>
|
|
public static IServiceCollection AddDealSecurity(this IServiceCollection services, string contentRootPath)
|
|
{
|
|
EncryptionKeyProvider keyProvider = new(contentRootPath);
|
|
services.AddSingleton(keyProvider);
|
|
services.AddSingleton<ISecretCipherFactory, SecretCipherFactory>();
|
|
services.AddSingleton<ISecretCipher>(provider => provider.GetRequiredService<ISecretCipherFactory>().Create());
|
|
return services;
|
|
}
|
|
}
|