Skip to content

Categories & Tasks

Categories solve the problem of needing different service registrations for different environments. Tag services with a category, and they’re only registered when that category is activated:

[Singleton(Category = "Test")]
public class MockPaymentService : IPaymentService;
[Singleton(Category = "Production")]
public class StripePaymentService : IPaymentService;
// Production startup — registers all uncategorized services + "Production" tagged services
builder.Services.AddShinyServiceRegistry("Production");
// Test startup — registers all uncategorized services + "Test" tagged services
services.AddShinyServiceRegistry("Test");
// Multiple categories
services.AddShinyServiceRegistry("Production", "Analytics");

Run initialization code after DI is fully configured by implementing IShinyStartupTask:

[Singleton]
public class DatabaseMigrationTask : IShinyStartupTask
{
public void Start()
{
// Run migrations, seed data, etc.
}
}
// Execute all registered startup tasks
app.Services.RunStartupTasks();

Additional extension methods on IServiceCollection:

// Register against all implemented interfaces
services.AddSingletonAsImplementedInterfaces<MyService>();
services.AddScopedAsImplementedInterfaces<MyService>();
// Keyed variant
services.AddSingletonAsImplementedInterfaces<MyService>("keyName");
// Check registrations
bool hasService = services.HasService<IMyService>();
bool hasImpl = services.HasImplementation<MyService>();
// Lazy resolution
Lazy<IMyService> lazy = services.GetLazyService<IMyService>(required: true);