dotnet --version
Demonstrate Singleton, Scoped, and Transient service lifetimes, service locator anti-pattern, and factory registrations.
1 using Microsoft.Extensions.DependencyInjection; 2 3 public static class ServiceCollectionExtensions 4 { 5 public static IServiceCollection AddMyFeature(this IServiceCollection services) 6 { 7 // Singleton: one instance for the entire app lifetime 8 services.AddSingleton<IConnectionPool, ConnectionPool>(); 9 10 // Scoped: one instance per HTTP request 11 services.AddScoped<IOrderService, OrderService>(); 12 services.AddScoped<IOrderRepository, OrderRepository>(); 13 14 // Transient: new instance every time it's requested 15 services.AddTransient<IEmailSender, SmtpEmailSender>(); 16 17 // Keyed services (NET 8+) 18 services.AddKeyedScoped<IPaymentProvider, StripeProvider>("stripe"); 19 services.AddKeyedScoped<IPaymentProvider, PayPalProvider>("paypal"); 20 21 // Factory registration 22 services.AddSingleton<IReportGeneratorFactory>(sp => 23 new ReportGeneratorFactory( 24 sp.GetRequiredService<IConnectionPool>(), 25 sp.GetRequiredService<ILogger<ReportGeneratorFactory>>() 26 )); 27 28 return services; 29 } 30 } 31 32 // Safe background service using IServiceScopeFactory 33 public class BackgroundWorker : BackgroundService 34 { 35 private readonly IServiceScopeFactory _scopeFactory; 36 37 public BackgroundWorker(IServiceScopeFactory scopeFactory) 38 { 39 _scopeFactory = scopeFactory; 40 } 41 42 protected override async Task ExecuteAsync(CancellationToken stoppingToken) 43 { 44 while (!stoppingToken.IsCancellationRequested) 45 { 46 // Create a scope for each unit of work to get Scoped services safely 47 using var scope = _scopeFactory.CreateScope(); 48 var orderService = scope.ServiceProvider.GetRequiredService<IOrderService>(); 49 await orderService.ProcessPendingOrdersAsync(stoppingToken); 50 await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken); 51 } 52 } 53 } 54
Sign in to share your feedback and join the discussion.