refactor(P2): DI 컴포지션 루트 + Scrutor 어셈블리 스캔 자동등록
컴파일타임 하드코딩(Bootstrap 14개 new + 수동 생성자 와이어링)을 제거 — 새 Provider는 클래스만 추가하면 자동 등록되고 그래프가 변환 엣지를 자동 흡수(확장성 토대). Strangler Fig 파사드로 호출부 무변경. - Core/ServiceCollectionExtensions.AddEverything2Everything: Scrutor FromAssembliesOf → AssignableTo<IConverterProvider> → AsSelfWithInterfaces(단일 싱글턴 공유) → Singleton. Heic(Magick)/Docx·Ocr·Hwpx(Pdf)/Llm(Settings) 생성자 의존 자동 해소. ProviderRegistry/Engine 등록. - Bootstrap.CreateDefault: 내부를 DI(BuildServiceProvider→GetRequiredService)로 교체하되 시그니처·동작 불변 — App/CLI/테스트 호출부 전부 무파손. - 패키지: Microsoft.Extensions.DependencyInjection 9.0.0, Scrutor 4.2.2 (CPM 경유). - DependencyInjectionTests: 14개 전수 해소 + 생성자 의존 자동 와이어링 + AsSelf 동일 인스턴스 + 공유 Settings + 파사드 하위호환 검증(적대적 리뷰의 'AsSelf 누락 silent 실패' 방어). App.xaml.cs Generic Host 전환·서비스로케이터 제거는 GUI 스모크가 필요해 P5(MVVM 생성자 주입)로 통합. 69개 테스트 전부 그린(65+4), 빌드 0경고/0오류, 골든마스터 녹색 유지(동작 불변).
This commit is contained in:
parent
6b524662a4
commit
8419bf30ff
5 changed files with 126 additions and 22 deletions
|
|
@ -26,6 +26,8 @@
|
|||
<PackageReference Include="PDFsharp" />
|
||||
<PackageReference Include="Svg.Skia" />
|
||||
<PackageReference Include="System.Security.Cryptography.ProtectedData" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
|
||||
<PackageReference Include="Scrutor" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -1,31 +1,19 @@
|
|||
using Everything2Everything.Core.Providers;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Everything2Everything.Core;
|
||||
|
||||
public static class Everything2EverythingBootstrap
|
||||
{
|
||||
/// <summary>
|
||||
/// 기본 변환 엔진을 구성한다. 내부적으로 DI 컨테이너(<see cref="ServiceCollectionExtensions.AddEverything2Everything"/>)로
|
||||
/// 모든 Provider를 어셈블리 스캔 자동 등록하고 ConversionEngine을 해소한다.
|
||||
/// 기존 호출부(App/CLI/테스트) 하위호환을 위한 얇은 파사드 — 시그니처·동작 불변.
|
||||
/// </summary>
|
||||
public static ConversionEngine CreateDefault(ISettingsStore? settings = null)
|
||||
{
|
||||
settings ??= new DpapiSettingsStore();
|
||||
var magick = new Converters.MagickProvider();
|
||||
var pdf = new Converters.PdfProvider();
|
||||
var providers = new IConverterProvider[]
|
||||
{
|
||||
magick,
|
||||
new Converters.HeicProvider(magick),
|
||||
pdf,
|
||||
new Converters.PdfToolProvider(),
|
||||
new Converters.DocxProvider(pdf),
|
||||
new Converters.HtmlProvider(),
|
||||
new Converters.HwpxProvider(),
|
||||
new Converters.OcrProvider(pdf),
|
||||
new Converters.DocumentProvider(),
|
||||
new Converters.DataProvider(),
|
||||
new Converters.VectorProvider(),
|
||||
new Converters.ImageOptimProvider(),
|
||||
new Converters.LlmProvider(settings),
|
||||
new Converters.FfmpegProvider(),
|
||||
};
|
||||
return new ConversionEngine(new ProviderRegistry(providers));
|
||||
var services = new ServiceCollection();
|
||||
services.AddEverything2Everything(settings);
|
||||
var provider = services.BuildServiceProvider();
|
||||
return provider.GetRequiredService<ConversionEngine>();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
using Everything2Everything.Core.Providers;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
|
||||
namespace Everything2Everything.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 변환 엔진의 DI 컴포지션 루트. 모든 IConverterProvider 구현을 어셈블리 스캔(Scrutor)으로 자동 등록해
|
||||
/// 컴파일타임 하드코딩(Bootstrap의 14개 new + 수동 생성자 와이어링)을 제거한다.
|
||||
/// 새 Provider는 클래스만 추가하면 자동 등록되고, 그래프가 그 변환 엣지를 자동 흡수한다(확장성 토대).
|
||||
/// </summary>
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddEverything2Everything(
|
||||
this IServiceCollection services,
|
||||
ISettingsStore? settings = null)
|
||||
{
|
||||
// 설정 저장소: 호출자가 공유 인스턴스(App의 DPAPI 저장소)를 주면 그걸 등록 — 키 변경이 LlmProvider에 즉시 반영.
|
||||
// 없으면 기본 DPAPI 저장소를 단 1회 등록.
|
||||
if (settings is not null)
|
||||
services.AddSingleton<ISettingsStore>(settings);
|
||||
else
|
||||
services.TryAddSingleton<ISettingsStore, DpapiSettingsStore>();
|
||||
|
||||
// IConverterProvider 구현 전수 자동 등록. AsSelfWithInterfaces =
|
||||
// 구체 타입을 단일 싱글턴으로 등록 + IConverterProvider는 그 인스턴스로 포워드한다.
|
||||
// → Heic(MagickProvider)/Docx·Ocr·Hwpx(PdfProvider)/Llm(ISettingsStore) 생성자 의존이
|
||||
// 동일 싱글턴 인스턴스로 자동 해소된다(다중 생성자는 MS.DI가 해소 가능한 최다 매개변수 생성자 선택).
|
||||
services.Scan(scan => scan
|
||||
.FromAssembliesOf(typeof(IConverterProvider))
|
||||
.AddClasses(c => c.AssignableTo<IConverterProvider>(), publicOnly: false)
|
||||
.AsSelfWithInterfaces()
|
||||
.WithSingletonLifetime());
|
||||
|
||||
// 그래프 빌더: 등록된 모든 IConverterProvider로부터 변환 그래프를 합성.
|
||||
services.AddSingleton<ProviderRegistry>(sp => new ProviderRegistry(sp.GetServices<IConverterProvider>()));
|
||||
services.AddSingleton<ConversionEngine>();
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue