using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using StellaOps.VexLens.Api; using StellaOps.VexLens.Caching; using StellaOps.VexLens.Consensus; using StellaOps.VexLens.Export; using StellaOps.VexLens.Integration; using StellaOps.VexLens.Orchestration; using StellaOps.VexLens.Mapping; using StellaOps.VexLens.Normalization; using StellaOps.VexLens.Observability; using StellaOps.VexLens.Options; using StellaOps.VexLens.Storage; using StellaOps.VexLens.Trust; using StellaOps.VexLens.Trust.SourceTrust; using StellaOps.VexLens.Verification; namespace StellaOps.VexLens.Extensions; /// /// Extension methods for registering VexLens services. /// public static class VexLensServiceCollectionExtensions { /// /// Adds VexLens consensus engine services to the service collection. /// public static IServiceCollection AddVexLens( this IServiceCollection services, IConfiguration configuration) { var section = configuration.GetSection(VexLensOptions.SectionName); services.Configure(section); var options = section.Get() ?? new VexLensOptions(); return services.AddVexLensCore(options); } /// /// Adds VexLens consensus engine services with explicit options. /// public static IServiceCollection AddVexLens( this IServiceCollection services, Action configure) { var options = new VexLensOptions(); configure(options); services.Configure(configure); return services.AddVexLensCore(options); } /// /// Adds VexLens services for testing with in-memory storage. /// public static IServiceCollection AddVexLensForTesting(this IServiceCollection services) { var options = new VexLensOptions { Storage = { Driver = "memory" }, Telemetry = { MetricsEnabled = false, TracingEnabled = false } }; return services.AddVexLensCore(options); } private static IServiceCollection AddVexLensCore( this IServiceCollection services, VexLensOptions options) { // Normalization services.TryAddSingleton(sp => { var registry = new VexNormalizerRegistry(); RegisterNormalizers(registry, options.Normalization); return registry; }); // Product mapping services.TryAddSingleton(); // Verification services.TryAddSingleton(); // Issuer directory - use in-memory by default, can be replaced services.TryAddSingleton(); // Trust engine (statement-level) services.TryAddSingleton(); // Source trust scoring (source-level) services.TryAddSingleton(Microsoft.Extensions.Options.Options.Create( SourceTrustScoreConfiguration.CreateDefault())); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); // Consensus engine services.TryAddSingleton(); // Storage RegisterStorage(services, options.Storage); // Event emitter - in-memory for now services.TryAddSingleton(); // API service services.TryAddScoped(); // Rationale service for AI/ML consumption services.TryAddScoped(); // Rationale cache for Advisory AI services.TryAddSingleton(); // Integration services services.TryAddScoped(); services.TryAddScoped(); // Export service for offline bundles services.TryAddScoped(); // Orchestrator job service for scheduling consensus compute services.TryAddScoped(); // Metrics if (options.Telemetry.MetricsEnabled) { services.TryAddSingleton(); } return services; } private static void RegisterNormalizers( VexNormalizerRegistry registry, VexLensNormalizationOptions options) { var enabledFormats = new HashSet( options.EnabledFormats, StringComparer.OrdinalIgnoreCase); if (enabledFormats.Contains("OpenVEX")) { registry.Register(new OpenVexNormalizer()); } if (enabledFormats.Contains("CSAF")) { registry.Register(new CsafVexNormalizer()); } if (enabledFormats.Contains("CycloneDX")) { registry.Register(new CycloneDxVexNormalizer()); } } private static void RegisterStorage( IServiceCollection services, VexLensStorageOptions options) { var driver = (options.Driver ?? "memory").Trim(); switch (driver.ToLowerInvariant()) { case "memory": services.TryAddSingleton(sp => { var emitter = sp.GetRequiredService(); return new InMemoryConsensusProjectionStore(emitter); }); break; default: throw new InvalidOperationException( $"Unsupported VexLens storage driver: '{options.Driver}'. Supported drivers: memory."); } } }