USE FOR: Registering and resolving services in the built-in .NET DI container, configuring service lifetimes (singleton, scoped, transient), keyed services, factory-based registrations, decorator patterns, and organizing registrations in extension methods. DO NOT USE FOR: Advanced DI features like interception, convention-based registration, or child containers (use Autofac or similar), or service locator anti-patterns.
Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.
Quelldateien prüfen
Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
USE FOR: Registering and resolving services in the built-in .NET DI container, configuring service lifetimes (singleton, scoped, transient), keyed services, factory-based registrations, decorator patterns, and organizing registrations in extension methods. DO NOT USE FOR: Advanced DI features like interception, convention-based registration, or child containers (use Autofac or similar), or service locator anti-patterns.
is the built-in dependency injection (DI) container for .NET applications. It provides constructor injection, service lifetime management (singleton, scoped, transient), and a registration API through . The container is deeply integrated with the .NET hosting model, ASP.NET Core, Entity Framework Core, and virtually all Microsoft.Extensions libraries.
Microsoft.Extensions.DependencyInjection
IServiceCollection
The built-in container is intentionally simple and fast. It supports constructor injection but not property injection, interception, or convention-based registration. For those advanced features, third-party containers like Autofac or Microsoft.Extensions.DependencyInjection.Abstractions-compatible containers can be plugged in as replacements.
Basic Service Registration
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var builder = Host.CreateApplicationBuilder(args);
// Register by interface and implementation
builder.Services.AddSingleton<IClock, SystemClock>();
builder.Services.AddScoped<IOrderRepository, SqlOrderRepository>();
builder.Services.AddTransient<IEmailSender, SmtpEmailSender>();
// Register a concrete type directly
builder.Services.AddScoped<OrderService>();
var app = builder.Build();
await app.RunAsync();
Service Lifetimes
Understanding when to use each lifetime is critical for correctness.
using Microsoft.Extensions.DependencyInjection;
publicstaticclassServiceRegistration
{
publicstatic IServiceCollection AddApplicationServices(this IServiceCollection services)
{
// Singleton: one instance for the entire application lifetime.// Use for stateless services, configuration, caches, and connection pools.
services.AddSingleton<IConnectionPool, RedisConnectionPool>();
// Scoped: one instance per scope (per HTTP request in ASP.NET Core).// Use for DbContext, Unit of Work, and request-scoped state.
services.AddScoped<IUnitOfWork, EfUnitOfWork>();
services.AddScoped<IUserContext, HttpUserContext>();
// Transient: a new instance every time it is requested.// Use for lightweight, stateless services with no shared state.
services.AddTransient<IValidator<Order>, OrderValidator>();
services.AddTransient<INotificationBuilder, NotificationBuilder>();
return services;
}
}
Lifetime
Instance Created
Disposed
Use When
Singleton
Once per application
At app shutdown
Stateless, thread-safe, or expensive to create
Scoped
Once per scope/request
At scope end
Request-specific state, DbContext
Transient
Every resolution
When scope ends (if IDisposable)
Lightweight, no shared state
Factory-Based Registration
Use a factory delegate when construction requires runtime logic.
Detect missing registrations at startup rather than at runtime.
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddApplicationServices();
// In Development, validate that all services can be resolvedif (builder.Environment.IsDevelopment())
{
builder.Host.UseDefaultServiceProvider(options =>
{
options.ValidateScopes = true; // Detect scoped-in-singleton bugs
options.ValidateOnBuild = true; // Verify all registrations resolve
});
}
var app = builder.Build();
await app.RunAsync();
Best Practices
Organize service registrations into focused IServiceCollection extension methods grouped by feature or layer (e.g., AddDataAccess, AddMessaging) and call them from Program.cs.
Choose lifetimes based on state: use singleton for stateless or thread-safe services, scoped for request-specific state like DbContext, and transient only for lightweight, no-state objects.
Never inject a scoped service into a singleton service -- this causes the scoped service to act as a singleton (captive dependency); enable ValidateScopes in development to detect this.
Enable ValidateOnBuild in development environments to catch missing registrations at startup rather than discovering them at runtime through InvalidOperationException.
Prefer constructor injection over IServiceProvider.GetService (service locator pattern); injecting IServiceProvider hides dependencies and makes code harder to test.
Use keyed services (.AddKeyedSingleton, [FromKeyedServices]) in .NET 8+ instead of custom factory patterns when the same interface has multiple implementations selected by name.
Register IDisposable and IAsyncDisposable services through the container rather than creating them manually, so the container manages their disposal at the correct time.
Inject IEnumerable<T> to receive all registered implementations of an interface, useful for plugin systems, validation chains, and health checks.
Avoid registering services with both a concrete type and an interface separately if they should share the same instance; use a forwarding registration pattern instead.
Write integration tests that build the real IServiceProvider from your registration code and call GetRequiredService<T> for critical services to verify the container is wired correctly.