Skip to content

Commit d7afa04

Browse files
committed
refactor: extract Gateway service registrations into focused extension methods
Extract 10 domain-specific extension methods from the 730+ line ConfigureCoreServices method to improve DI graph comprehension and maintainability: - WebhookServicesExtensions: webhook delivery, metrics, circuit breakers - HttpClientServicesExtensions: image/video download, function provider clients - ObservabilityExtensions: OpenTelemetry metrics/tracing, query monitoring - SignalRServicesExtensions: reliability services (acknowledgment, queue, monitor) - BillingServicesExtensions: cost calculation, billing/pricing audit - DatabaseServicesExtensions: connection management, DbContext factory - BatchOperationServicesExtensions: TaskHub, batch operations, idempotency - AuditServicesExtensions: request log, function call audit - MediaGenerationExtensions: video generation, metrics, orchestrators - FunctionServicesExtensions: function repositories, execution, orchestration Reduces ConfigureCoreServices from 843 to 192 lines (~77% reduction).
1 parent b61d3b7 commit d7afa04

11 files changed

+855
-718
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using ConduitLLM.Configuration.Interfaces;
2+
using ConduitLLM.Configuration.Services;
3+
using ConduitLLM.Core.Extensions;
4+
using ConduitLLM.Functions.Interfaces;
5+
6+
namespace ConduitLLM.Gateway.Extensions;
7+
8+
/// <summary>
9+
/// Extension methods for registering audit services
10+
/// </summary>
11+
public static class AuditServicesExtensions
12+
{
13+
/// <summary>
14+
/// Adds audit services including request log and function call audit services with leader election
15+
/// </summary>
16+
public static IServiceCollection AddAuditServices(this IServiceCollection services)
17+
{
18+
// Request Log Service - uses batch processing like other audit services
19+
services.AddSingleton<IRequestLogService, RequestLogService>();
20+
services.AddLeaderElectedHostedService<RequestLogService>(
21+
provider => (RequestLogService)provider.GetRequiredService<IRequestLogService>(),
22+
"RequestLogService");
23+
24+
// Register Function Call Audit service with leader election
25+
services.AddSingleton<IFunctionCallAuditService, FunctionCallAuditService>();
26+
services.AddLeaderElectedHostedService<FunctionCallAuditService>(
27+
provider => (FunctionCallAuditService)provider.GetRequiredService<IFunctionCallAuditService>(),
28+
"FunctionCallAuditService");
29+
30+
return services;
31+
}
32+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using ConduitLLM.Configuration.Interfaces;
2+
using ConduitLLM.Configuration.Repositories;
3+
using ConduitLLM.Core.Interfaces;
4+
using ConduitLLM.Core.Services;
5+
using ConduitLLM.Core.Services.BatchOperations;
6+
using ConduitLLM.Gateway.Services;
7+
8+
namespace ConduitLLM.Gateway.Extensions;
9+
10+
/// <summary>
11+
/// Extension methods for registering batch operation services
12+
/// </summary>
13+
public static class BatchOperationServicesExtensions
14+
{
15+
/// <summary>
16+
/// Adds batch operation services including TaskHub, history, notification, and batch operations
17+
/// </summary>
18+
public static IServiceCollection AddBatchOperationServices(this IServiceCollection services)
19+
{
20+
// Register TaskHub Service for ITaskHub interface
21+
services.AddSingleton<ITaskHub, TaskHubService>();
22+
23+
// Register Batch Operation Services
24+
services.AddScoped<IBatchOperationHistoryRepository, BatchOperationHistoryRepository>();
25+
services.AddScoped<IBatchOperationHistoryService, BatchOperationHistoryService>();
26+
services.AddSingleton<IBatchOperationNotificationService, BatchOperationNotificationService>();
27+
services.AddScoped<IBatchOperationService, BatchOperationService>();
28+
29+
// Register Batch Operation Idempotency Service (Redis-based)
30+
services.AddSingleton<IBatchOperationIdempotencyService, BatchOperationIdempotencyService>();
31+
32+
// Register batch operations
33+
services.AddScoped<IBatchVirtualKeyUpdateOperation, BatchVirtualKeyUpdateOperation>();
34+
services.AddScoped<IBatchWebhookSendOperation, BatchWebhookSendOperation>();
35+
36+
// Register spend update batch operation
37+
services.AddScoped<BatchSpendUpdateOperation>();
38+
39+
return services;
40+
}
41+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using ConduitLLM.Configuration.Interfaces;
2+
using ConduitLLM.Configuration.Services;
3+
using ConduitLLM.Core.Extensions;
4+
using ConduitLLM.Core.Interfaces;
5+
using ConduitLLM.Core.Services;
6+
using ConduitLLM.Gateway.Services;
7+
8+
namespace ConduitLLM.Gateway.Extensions;
9+
10+
/// <summary>
11+
/// Extension methods for registering billing and pricing services
12+
/// </summary>
13+
public static class BillingServicesExtensions
14+
{
15+
/// <summary>
16+
/// Adds billing and pricing services including cost calculation, billing audit, and pricing rules engine
17+
/// </summary>
18+
public static IServiceCollection AddBillingAndPricingServices(this IServiceCollection services)
19+
{
20+
// Model costs tracking service
21+
services.AddScoped<IModelCostService, ModelCostService>();
22+
23+
// Cost calculation service
24+
services.AddScoped<ICostCalculationService, CostCalculationService>();
25+
26+
// Tool cost calculation service for provider tool billing
27+
services.AddScoped<IToolCostCalculationService, ToolCostCalculationService>();
28+
29+
// Ephemeral key service for direct browser-to-API authentication (used for all direct access including SignalR)
30+
services.AddScoped<IEphemeralKeyService, EphemeralKeyService>();
31+
32+
// Virtual key service (Configuration layer - used by RealtimeUsageTracker)
33+
services.AddScoped<ConduitLLM.Configuration.Interfaces.IVirtualKeyService, ConduitLLM.Configuration.Services.VirtualKeyService>();
34+
35+
// Billing audit service for comprehensive billing event tracking - with leader election
36+
services.AddSingleton<IBillingAuditService, BillingAuditService>();
37+
services.AddLeaderElectedHostedService<BillingAuditService>(
38+
provider => (BillingAuditService)provider.GetRequiredService<IBillingAuditService>(),
39+
"BillingAuditService");
40+
41+
// Pricing rules engine services for flexible rules-based pricing
42+
services.AddScoped<IPricingRulesEvaluator, PricingRulesEvaluator>();
43+
services.AddScoped<IPricingRulesValidator, PricingRulesValidator>();
44+
45+
// Cached pricing rules service for parsed configuration caching
46+
services.AddSingleton<ICachedPricingRulesService, CachedPricingRulesService>();
47+
48+
// Pricing audit service for rules-based pricing evaluation tracking - with leader election
49+
services.AddSingleton<IPricingAuditService, PricingAuditService>();
50+
services.AddLeaderElectedHostedService<PricingAuditService>(
51+
provider => (PricingAuditService)provider.GetRequiredService<IPricingAuditService>(),
52+
"PricingAuditService");
53+
54+
return services;
55+
}
56+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
using System.Text.RegularExpressions;
2+
using ConduitLLM.Configuration;
3+
using ConduitLLM.Configuration.Interceptors;
4+
using ConduitLLM.Core.Data;
5+
using Microsoft.EntityFrameworkCore;
6+
7+
namespace ConduitLLM.Gateway.Extensions;
8+
9+
/// <summary>
10+
/// Extension methods for registering database services
11+
/// </summary>
12+
public static class DatabaseServicesExtensions
13+
{
14+
/// <summary>
15+
/// Adds database services including connection management, DbContext factory, and query monitoring
16+
/// </summary>
17+
public static IServiceCollection AddDatabaseServices(this IServiceCollection services, IConfiguration configuration)
18+
{
19+
// Get connection string from environment variables
20+
var connectionStringManager = new ConnectionStringManager();
21+
// Pass "CoreAPI" to get Gateway API-specific connection pool settings
22+
var (dbProvider, dbConnectionString) = connectionStringManager.GetProviderAndConnectionString("CoreAPI", msg => Console.WriteLine(msg));
23+
24+
// Log the connection pool settings for verification
25+
if (dbProvider == "postgres" && dbConnectionString.Contains("MaxPoolSize"))
26+
{
27+
Console.WriteLine($"[Conduit] Gateway API database connection pool configured:");
28+
var match = Regex.Match(dbConnectionString, @"MinPoolSize=(\d+);MaxPoolSize=(\d+)");
29+
if (match.Success)
30+
{
31+
Console.WriteLine($"[Conduit] Min Pool Size: {match.Groups[1].Value}");
32+
Console.WriteLine($"[Conduit] Max Pool Size: {match.Groups[2].Value}");
33+
}
34+
}
35+
36+
// Only PostgreSQL is supported
37+
if (dbProvider != "postgres")
38+
{
39+
throw new InvalidOperationException($"Only PostgreSQL is supported. Invalid provider: {dbProvider}");
40+
}
41+
42+
// Register DbContext Factory with query monitoring interceptor
43+
services.AddDbContextFactory<ConduitDbContext>((sp, options) =>
44+
{
45+
var interceptor = sp.GetRequiredService<QueryMonitoringInterceptor>();
46+
options.UseNpgsql(dbConnectionString)
47+
.AddInterceptors(interceptor);
48+
});
49+
Console.WriteLine("[Conduit] Query monitoring interceptor configured for performance tracking");
50+
51+
// Also add scoped registration from factory for services that need direct injection
52+
services.AddScoped<ConduitDbContext>(provider =>
53+
{
54+
var factory = provider.GetService<IDbContextFactory<ConduitDbContext>>();
55+
if (factory == null)
56+
{
57+
throw new InvalidOperationException("IDbContextFactory<ConfigurationDbContext> is not registered");
58+
}
59+
return factory.CreateDbContext();
60+
});
61+
62+
return services;
63+
}
64+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using ConduitLLM.Configuration.Repositories;
2+
using ConduitLLM.Core.Interfaces;
3+
using ConduitLLM.Core.Services;
4+
using ConduitLLM.Functions.Interfaces;
5+
using ConduitLLM.Functions.Services;
6+
7+
namespace ConduitLLM.Gateway.Extensions;
8+
9+
/// <summary>
10+
/// Extension methods for registering function services
11+
/// </summary>
12+
public static class FunctionServicesExtensions
13+
{
14+
/// <summary>
15+
/// Adds function services including repositories, execution, cost calculation, and agentic orchestration
16+
/// </summary>
17+
public static IServiceCollection AddFunctionServices(this IServiceCollection services)
18+
{
19+
// Register Function repositories
20+
services.AddScoped<IFunctionConfigurationRepository, FunctionConfigurationRepository>();
21+
22+
// Register Function services
23+
services.AddScoped<IFunctionCostService, FunctionCostService>();
24+
services.AddScoped<IFunctionCostCalculationService, FunctionCostCalculationService>();
25+
services.AddScoped<IFunctionClientFactory, FunctionClientFactory>();
26+
services.AddScoped<IFunctionExecutionService, FunctionExecutionService>();
27+
services.AddScoped<FunctionParameterValidationService>();
28+
29+
// Register Agentic Function Calling services
30+
services.AddScoped<IFunctionDiscoveryService, FunctionDiscoveryService>();
31+
services.AddScoped<IAgenticOrchestrationService, AgenticOrchestrationService>();
32+
33+
return services;
34+
}
35+
}

0 commit comments

Comments
 (0)