/
afanasevn
/
PdfEncoder
Обзор
Документация
Войти
/
afanasevn
/
PdfEncoder
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/PdfEncoder.Infrastructure/DependencyInjection.cs
155 строк
6 KB
IBS\NAfanasev
Parse results functional update
07 июл 2026, 00:06
07 июл 2026, 00:06
8e97443
Код
Авторство
О чём код?
using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.AI; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Options; using PdfEncoder.Application.Abstractions; using PdfEncoder.Application.Options; using PdfEncoder.Infrastructure.Hashing; using PdfEncoder.Infrastructure.Health; using PdfEncoder.Infrastructure.Jobs; using PdfEncoder.Infrastructure.Llm; using PdfEncoder.Infrastructure.Ocr; using PdfEncoder.Infrastructure.Pdf; using PdfEncoder.Infrastructure.Persistence; using PdfEncoder.Infrastructure.Pipeline; using PdfEncoder.Infrastructure.Storage; namespace PdfEncoder.Infrastructure; /// <summary> /// Регистрация сервисов Infrastructure в DI. /// </summary> public static class DependencyInjection { /// <summary> /// Подключает опции, health checks и инфраструктурные сервисы. /// </summary> public static IServiceCollection AddInfrastructure( this IServiceCollection services, IConfiguration configuration) { services.AddOptions<LlmModelOptions>() .Bind(configuration.GetSection(LlmModelOptions.SectionName)) .ValidateOnStart(); services.AddOptions<UploadOptions>() .Bind(configuration.GetSection(UploadOptions.SectionName)); services.AddOptions<PipelineOptions>() .Bind(configuration.GetSection(PipelineOptions.SectionName)); services.AddOptions<TesseractOptions>() .Bind(configuration.GetSection(TesseractOptions.SectionName)); services.AddOptions<StorageOptions>() .Bind(configuration.GetSection(StorageOptions.SectionName)); services.AddOptions<CorsOptions>() .Bind(configuration.GetSection(CorsOptions.SectionName)); services.AddSingleton<IValidateOptions<LlmModelOptions>, LlmModelOptionsValidator>(); services.AddPersistence(configuration); services.AddHttpClient("LlmHealth", client => { client.Timeout = TimeSpan.FromSeconds(5); }); var healthChecks = services.AddHealthChecks() .AddCheck<StorageHealthCheck>("storage"); var connectionString = configuration.GetConnectionString("DefaultConnection"); if (!string.IsNullOrWhiteSpace(connectionString) && !IsSqliteConnectionString(connectionString)) { healthChecks.AddNpgSql(connectionString, name: "database"); } healthChecks.AddCheck<LlmHealthCheck>("llm"); services.AddPdfPipeline(); services.AddLlmServices(); return services; } /// <summary> /// Регистрирует EF Core, file storage и document job service. /// </summary> public static IServiceCollection AddPersistence( this IServiceCollection services, IConfiguration configuration) { var connectionString = configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("ConnectionStrings:DefaultConnection is not configured."); services.AddDbContext<PdfEncoderDbContext>(options => { if (IsSqliteConnectionString(connectionString)) { options.UseSqlite(connectionString); return; } options.UseNpgsql(connectionString, npgsql => npgsql.MigrationsAssembly(typeof(PdfEncoderDbContext).Assembly.FullName)); }); services.AddScoped<IFileStorage, LocalFileStorage>(); services.AddScoped<IDocumentJobService, DocumentJobService>(); services.AddHostedService<DocumentJobRecoveryHostedService>(); return services; } private static bool IsSqliteConnectionString(string connectionString) { return connectionString.Contains("Data Source=", StringComparison.OrdinalIgnoreCase) || connectionString.Contains("Filename=", StringComparison.OrdinalIgnoreCase); } /// <summary> /// Регистрирует LLM-клиент, detectors и usage log store. /// </summary> public static IServiceCollection AddLlmServices(this IServiceCollection services) { services.AddSingleton<PromptTemplateProvider>(); services.AddScoped<ILlmUsageLogStore, EfLlmUsageLogStore>(); services.AddSingleton<OpenAiCompatibleChatClient>(); services.AddSingleton<IChatClient>(sp => sp.GetRequiredService<OpenAiCompatibleChatClient>()); services.AddScoped<ILlmClient, LlmClient>(); services.AddScoped<IDocumentTypeDetector, DocumentTypeDetector>(); services.AddScoped<IContentHintGenerator, DocumentContentHintGenerator>(); services.AddScoped<IStructuredExtractor, StructuredExtractor>(); services.AddScoped<IParseResultValidator, ParseResultValidator>(); services.AddScoped<IDocumentParsePipeline, DocumentParsePipeline>(); return services; } /// <summary> /// Регистрирует локальный PDF pipeline и фоновый worker. /// </summary> public static IServiceCollection AddPdfPipeline(this IServiceCollection services) { services.AddSingleton<IDocLibProvider, DocLibProvider>(); services.AddSingleton<IContentHashService, ContentHashService>(); services.AddSingleton<IDocumentJobQueue, DocumentJobQueue>(); services.AddScoped<IPdfInputValidator, PdfInputValidator>(); services.AddScoped<IPdfClassifier, PdfClassifier>(); services.AddScoped<IPdfTextExtractor, PdfTextExtractor>(); services.AddScoped<IPdfPageRenderer, PdfPageRenderer>(); services.AddScoped<IOcrService, TesseractOcrService>(); services.AddScoped<IDocumentContextBuilder, DocumentContextBuilder>(); services.AddScoped<IPdfParsePipeline, PdfParsePipeline>(); services.AddHostedService<DocumentProcessingBackgroundService>(); return services; } }