--- author: rick-anderson ms.author: riande ms.date: 8/17/2024 --- :::moniker range="= aspnetcore-8.0" By [Kirk Larkin](https://twitter.com/serpent5), [Steve Smith](https://ardalis.com/), and [Brandon Dahler](https://github.com/brandondahler) ASP.NET Core supports the dependency injection (DI) software design pattern, which is a technique for achieving [Inversion of Control (IoC)](/dotnet/standard/modern-web-apps-azure-architecture/architectural-principles#dependency-inversion) between classes and their dependencies. For more information specific to dependency injection within MVC controllers, see . For information on using dependency injection in applications other than web apps, see [Dependency injection in .NET](/dotnet/core/extensions/dependency-injection). For more information on dependency injection of options, see . This topic provides information on dependency injection in ASP.NET Core. The primary documentation on using dependency injection is contained in [Dependency injection in .NET](/dotnet/core/extensions/dependency-injection). [View or download sample code](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/dependency-injection/samples) ([how to download](xref:index#how-to-download-a-sample)) ## Overview of dependency injection A *dependency* is an object that another object depends on. Examine the following `MyDependency` class with a `WriteMessage` method that other classes depend on: [!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DIwebApp/MyDependency.cs?name=snippet)] A class can create an instance of the `MyDependency` class to make use of its `WriteMessage` method. In the following example, the `MyDependency` class is a dependency of the `IndexModel` class: [!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DIwebApp/Pages/Index.cshtml.cs?name=snippet)] The class creates and directly depends on the `MyDependency` class. Code dependencies, such as in the previous example, are problematic and should be avoided for the following reasons: * To replace `MyDependency` with a different implementation, the `IndexModel` class must be modified. * If `MyDependency` has dependencies, they must also be configured by the `IndexModel` class. In a large project with multiple classes depending on `MyDependency`, the configuration code becomes scattered across the app. * This implementation is difficult to unit test. Dependency injection addresses these problems through: * The use of an interface or base class to abstract the dependency implementation. * Registration of the dependency in a service container. ASP.NET Core provides a built-in service container, . Services are typically registered in the app's `Program.cs` file. * *Injection* of the service into the constructor of the class where it's used. The framework takes on the responsibility of creating an instance of the dependency and disposing of it when it's no longer needed. In the [sample app](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/dependency-injection/samples/6.x), the `IMyDependency` interface defines the `WriteMessage` method: [!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DependencyInjectionSample/Interfaces/IMyDependency.cs?name=snippet1)] This interface is implemented by a concrete type, `MyDependency`: [!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DependencyInjectionSample/Services/MyDependency.cs?name=snippet1)] The sample app registers the `IMyDependency` service with the concrete type `MyDependency`. The method registers the service with a scoped lifetime, the lifetime of a single request. [Service lifetimes](#service-lifetimes) are described later in this topic. [!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DependencyInjectionSample/Program.cs?name=snippet1)] In the sample app, the `IMyDependency` service is requested and used to call the `WriteMessage` method: [!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DependencyInjectionSample/Pages/Index2.cshtml.cs?name=snippet1)] By using the DI pattern, the controller or Razor Page: * Doesn't use the concrete type `MyDependency`, only the `IMyDependency` interface it implements. That makes it easy to change the implementation without modifying the controller or Razor Page. * Doesn't create an instance of `MyDependency`, it's created by the DI container. The implementation of the `IMyDependency` interface can be improved by using the built-in logging API: [!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DependencyInjectionSample/Services/MyDependency.cs?name=snippet2)] The updated `Program.cs` registers the new `IMyDependency` implementation: [!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DependencyInjectionSample/Program.cs?name=snippet2)] `MyDependency2` depends on , which it requests in the constructor. `ILogger` is a [framework-provided service](#framework-provided-services). It's not unusual to use dependency injection in a chained fashion. Each requested dependency in turn requests its own dependencies. The container resolves the dependencies in the graph and returns the fully resolved service. The collective set of dependencies that must be resolved is typically referred to as a *dependency tree*, *dependency graph*, or *object graph*. The container resolves `ILogger` by taking advantage of [(generic) open types](/dotnet/csharp/language-reference/language-specification/types#843-open-and-closed-types), eliminating the need to register every [(generic) constructed type](/dotnet/csharp/language-reference/language-specification/types#84-constructed-types). In dependency injection terminology, a service: * Is typically an object that provides a service to other objects, such as the `IMyDependency` service. * Is not related to a web service, although the service may use a web service. The framework provides a robust [logging](xref:fundamentals/logging/index) system. The `IMyDependency` implementations shown in the preceding examples were written to demonstrate basic DI, not to implement logging. Most apps shouldn't need to write loggers. The following code demonstrates using the default logging, which doesn't require any services to be registered: [!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DependencyInjectionSample/Pages/About.cshtml.cs?name=snippet)] Using the preceding code, there is no need to update `Program.cs`, because [logging](xref:fundamentals/logging/index) is provided by the framework. ## Register groups of services with extension methods The ASP.NET Core framework uses a convention for registering a group of related services. The convention is to use a single `Add{GROUP_NAME}` extension method to register all of the services required by a framework feature. For example, the extension method registers the services required for MVC controllers. The following code is generated by the Razor Pages template using individual user accounts and shows how to add additional services to the container using the extension methods and : [!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DependencyInjectionSample/ProgramEF.cs?name=snippet)] [!INCLUDE[](~/includes/combine-di6.md)] ## Service lifetimes See [Service lifetimes](/dotnet/core/extensions/dependency-injection#service-lifetimes) in [Dependency injection in .NET](/dotnet/core/extensions/dependency-injection) To use scoped services in middleware, use one of the following approaches: * Inject the service into the middleware's `Invoke` or `InvokeAsync` method. Using [constructor injection](xref:mvc/controllers/dependency-injection#constructor-injection) throws a runtime exception because it forces the scoped service to behave like a singleton. The sample in the [Lifetime and registration options](#lifetime-and-registration-options) section demonstrates the `InvokeAsync` approach. * Use [Factory-based middleware](xref:fundamentals/middleware/extensibility). Middleware registered using this approach is activated per client request (connection), which allows scoped services to be injected into the middleware's constructor. For more information, see . ## Service registration methods See [Service registration methods](/dotnet/core/extensions/dependency-injection#service-registration-methods) in [Dependency injection in .NET](/dotnet/core/extensions/dependency-injection) It's common to use multiple implementations when [mocking types for testing](xref:test/integration-tests#inject-mock-services). Registering a service with only an implementation type is equivalent to registering that service with the same implementation and service type. This is why multiple implementations of a service cannot be registered using the methods that don't take an explicit service type. These methods can register multiple *instances* of a service, but they will all have the same *implementation* type. Any of the above service registration methods can be used to register multiple service instances of the same service type. In the following example, `AddSingleton` is called twice with `IMyDependency` as the service type. The second call to `AddSingleton` overrides the previous one when resolved as `IMyDependency` and adds to the previous one when multiple services are resolved via `IEnumerable`. Services appear in the order they were registered when resolved via `IEnumerable<{SERVICE}>`. ```csharp services.AddSingleton(); services.AddSingleton(); public class MyService { public MyService(IMyDependency myDependency, IEnumerable myDependencies) { Trace.Assert(myDependency is DifferentDependency); var dependencyArray = myDependencies.ToArray(); Trace.Assert(dependencyArray[0] is MyDependency); Trace.Assert(dependencyArray[1] is DifferentDependency); } } ``` ### Keyed services *Keyed services* refers to a mechanism for registering and retrieving Dependency Injection (DI) services using keys. A service is associated with a key by calling (or `AddKeyedScoped` or `AddKeyedTransient`) to register it. Access a registered service by specifying the key with the [`[FromKeyedServices]`](xref:Microsoft.Extensions.DependencyInjection.FromKeyedServicesAttribute) attribute. The following code shows how to use keyed services: :::code language="csharp" source="~/../AspNetCore.Docs.Samples/samples/KeyedServices/Program.cs" highlight="6,7,12-14,39,47"::: ## Constructor injection behavior See [Constructor injection behavior](/dotnet/core/extensions/dependency-injection#constructor-injection-behavior) in [Dependency injection in .NET](/dotnet/core/extensions/dependency-injection) ## Entity Framework contexts By default, Entity Framework contexts are added to the service container using the [scoped lifetime](#service-lifetimes) because web app database operations are normally scoped to the client request. To use a different lifetime, specify the lifetime by using an overload. Services of a given lifetime shouldn't use a database context with a lifetime that's shorter than the service's lifetime. ## Lifetime and registration options To demonstrate the difference between service lifetimes and their registration options, consider the following interfaces that represent a task as an operation with an identifier, `OperationId`. Depending on how the lifetime of an operation's service is configured for the following interfaces, the container provides either the same or different instances of the service when requested by a class: [!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DependencyInjectionSample/Interfaces/IOperation.cs?name=snippet1)] The following `Operation` class implements all of the preceding interfaces. The `Operation` constructor generates a GUID and stores the last 4 characters in the `OperationId` property: [!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DependencyInjectionSample/Models/Operation.cs?name=snippet1)] The following code creates multiple registrations of the `Operation` class according to the named lifetimes: [!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DependencyInjectionSample/Program.cs?name=snippet3&highlight=5-7,20)] The sample app demonstrates object lifetimes both within and between requests. The `IndexModel` and the middleware request each kind of `IOperation` type and log the `OperationId` for each: [!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DependencyInjectionSample/Pages/Index.cshtml.cs?name=snippet1)] Similar to the `IndexModel`, the middleware resolves the same services: [!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DependencyInjectionSample/Middleware/MyMiddleware.cs?name=snippet)] Scoped and transient services must be resolved in the `InvokeAsync` method: [!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DependencyInjectionSample/Middleware/MyMiddleware.cs?name=snippet2&highlight=2)] The logger output shows: * *Transient* objects are always different. The transient `OperationId` value is different in the `IndexModel` and in the middleware. * *Scoped* objects are the same for a given request but differ across each new request. * *Singleton* objects are the same for every request. To reduce the logging output, set "Logging:LogLevel:Microsoft:Error" in the `appsettings.Development.json` file: [!code-json[](~/fundamentals/dependency-injection/samples/3.x/DependencyInjectionSample/appsettings.Development.json?highlight=7)] ## Resolve a service at app start up The following code shows how to resolve a scoped service for a limited duration when the app starts: [!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/WebApp1/Program.cs?highlight=3,7-13)] ## Scope validation See [Constructor injection behavior](/dotnet/core/extensions/dependency-injection#constructor-injection-behavior) in [Dependency injection in .NET](/dotnet/core/extensions/dependency-injection) For more information, see [Scope validation](xref:fundamentals/host/web-host#scope-validation). ## Request Services Services and their dependencies within an ASP.NET Core request are exposed through . The framework creates a scope per request, and `RequestServices` exposes the scoped service provider. All scoped services are valid for as long as the request is active. > [!NOTE] > Prefer requesting dependencies as constructor parameters over resolving services from `RequestServices`. Requesting dependencies as constructor parameters yields classes that are easier to test. ## Design services for dependency injection When designing services for dependency injection: * Avoid stateful, static classes and members. Avoid creating global state by designing apps to use singleton services instead. * Avoid direct instantiation of dependent classes within services. Direct instantiation couples the code to a particular implementation. * Make services small, well-factored, and easily tested. If a class has a lot of injected dependencies, it might be a sign that the class has too many responsibilities and violates the [Single Responsibility Principle (SRP)](/dotnet/standard/modern-web-apps-azure-architecture/architectural-principles#single-responsibility). Attempt to refactor the class by moving some of its responsibilities into new classes. Keep in mind that Razor Pages page model classes and MVC controller classes should focus on UI concerns. ### Disposal of services The container calls for the types it creates. Services resolved from the container should never be disposed by the developer. If a type or factory is registered as a singleton, the container disposes the singleton automatically. In the following example, the services are created by the service container and disposed automatically: dependency-injection\samples\6.x\DIsample2\DIsample2\Services\Service1.cs [!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DIsample2/DIsample2/Services/Service1.cs?name=snippet)] [!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DIsample2/DIsample2/Program.cs?name=snippet)] [!code-csharp[](~/fundamentals/dependency-injection/samples/3.x/DIsample2/DIsample2/Pages/Index.cshtml.cs?name=snippet)] The debug console shows the following output after each refresh of the Index page: ```console Service1: IndexModel.OnGet Service2: IndexModel.OnGet Service3: IndexModel.OnGet, MyKey = MyKey from appsettings.Developement.json Service1.Dispose ``` ### Services not created by the service container Consider the following code: [!code-csharp[](~/fundamentals/dependency-injection/samples/6.x/DIsample2/DIsample2/Program.cs?name=snippet3)] In the preceding code: * The service instances aren't created by the service container. * The framework doesn't dispose of the services automatically. * The developer is responsible for disposing the services. ### IDisposable guidance for Transient and shared instances See [IDisposable guidance for Transient and shared instance](/dotnet/core/extensions/dependency-injection-guidelines#idisposable-guidance-for-transient-and-shared-instances) in [Dependency injection in .NET](/dotnet/core/extensions/dependency-injection) ## Default service container replacement See [Default service container replacement](/dotnet/core/extensions/dependency-injection-guidelines#default-service-container-replacement) in [Dependency injection in .NET](/dotnet/core/extensions/dependency-injection) ## Recommendations See [Recommendations](/dotnet/core/extensions/dependency-injection-guidelines#recommendations) in [Dependency injection in .NET](/dotnet/core/extensions/dependency-injection) * Avoid using the *service locator pattern*. For example, don't invoke to obtain a service instance when you can use DI instead: **Incorrect:** ![Incorrect code](~/fundamentals/dependency-injection/_static/bad.png) **Correct**: ```csharp public class MyClass { private readonly IOptionsMonitor _optionsMonitor; public MyClass(IOptionsMonitor optionsMonitor) { _optionsMonitor = optionsMonitor; } public void MyMethod() { var option = _optionsMonitor.CurrentValue.Option; ... } } ``` * Another service locator variation to avoid is injecting a factory that resolves dependencies at runtime. Both of these practices mix [Inversion of Control](/dotnet/standard/modern-web-apps-azure-architecture/architectural-principles#dependency-inversion) strategies. * Avoid static access to `HttpContext` (for example, [IHttpContextAccessor.HttpContext](xref:Microsoft.AspNetCore.Http.IHttpContextAccessor.HttpContext)). DI is an *alternative* to static/global object access patterns. You may not be able to realize the benefits of DI if you mix it with static object access. ## Recommended patterns for multi-tenancy in DI [Orchard Core](https://github.com/OrchardCMS/OrchardCore) is an application framework for building modular, multi-tenant applications on ASP.NET Core. For more information, see the [Orchard Core Documentation](https://docs.orchardcore.net). See the [Orchard Core samples](https://github.com/OrchardCMS/OrchardCore.Samples) for examples of how to build modular and multi-tenant apps using just the Orchard Core Framework without any of its CMS-specific features. ## Framework-provided services `Program.cs` registers services that the app uses, including platform features, such as Entity Framework Core and ASP.NET Core MVC. Initially, the `IServiceCollection` provided to `Program.cs` has services defined by the framework depending on [how the host was configured](xref:fundamentals/index#host). For apps based on the ASP.NET Core templates, the framework registers more than 250 services. The following table lists a small sample of these framework-registered services: | Service Type | Lifetime | |-------------------------------------------------------------------------------------------------|-----------| | | Transient | | | Singleton | | | Singleton | | | Singleton | | | Transient | | | Singleton | | | Transient | | | Singleton | | | Singleton | | | Singleton | | | Transient | | | Singleton | | | Singleton | | | Singleton | ## Additional resources * * * * * [NDC Conference Patterns for DI app development](https://www.youtube.com/watch?v=x-C-CNBVTaY) * * * [Understand dependency injection basics in .NET](/dotnet/core/extensions/dependency-injection-basics) * [Dependency injection guidelines](/dotnet/core/extensions/dependency-injection-guidelines) * [Tutorial: Use dependency injection in .NET](/dotnet/core/extensions/dependency-injection-usage) * [.NET dependency injection](/dotnet/core/extensions/dependency-injection) * [ASP.NET CORE DEPENDENCY INJECTION: WHAT IS THE ISERVICECOLLECTION?](https://www.stevejgordon.co.uk/aspnet-core-dependency-injection-what-is-the-iservicecollection) * [Four ways to dispose IDisposables in ASP.NET Core](https://andrewlock.net/four-ways-to-dispose-idisposables-in-asp-net-core/) * [Writing Clean Code in ASP.NET Core with Dependency Injection (MSDN)](/archive/msdn-magazine/2016/may/asp-net-writing-clean-code-in-asp-net-core-with-dependency-injection) * [Explicit Dependencies Principle](/dotnet/standard/modern-web-apps-azure-architecture/architectural-principles#explicit-dependencies) * [Inversion of Control Containers and the Dependency Injection Pattern (Martin Fowler)](https://www.martinfowler.com/articles/injection.html) * [How to register a service with multiple interfaces in ASP.NET Core DI](https://andrewlock.net/how-to-register-a-service-with-multiple-interfaces-for-in-asp-net-core-di/) :::moniker-end