--- title: Dependency injection in ASP.NET Core author: guardrex description: Learn how ASP.NET Core implements dependency injection and how to use it. ms.author: riande ms.custom: mvc ms.date: 07/02/2018 uid: fundamentals/dependency-injection --- # Dependency injection in ASP.NET Core By [Steve Smith](https://ardalis.com/), [Scott Addie](https://scottaddie.com), and [Luke Latham](https://github.com/guardrex) ASP.NET Core supports the dependency injection (DI) software design pattern, which is a technique for achieving [Inversion of Control (IoC)](https://deviq.com/inversion-of-control/) between classes and their dependencies. For more information specific to dependency injection within MVC controllers, see . [View or download sample code](https://github.com/aspnet/Docs/tree/master/aspnetcore/fundamentals/dependency-injection/samples) ([how to download](xref:tutorials/index#how-to-download-a-sample)) ## Overview of dependency injection A *dependency* is any object that another object requires. Examine the following `MyDependency` class with a `WriteMessage` method that other classes in an app depend upon: ```csharp public class MyDependency { public MyDependency() { } public Task WriteMessage(string message) { Console.WriteLine( $"MyDependency.WriteMessage called. Message: {message}"); return Task.FromResult(0); } } ``` ::: moniker range=">= aspnetcore-2.1" An instance of the `MyDependency` class can be created to make the `WriteMessage` method available to a class. The `MyDependency` class is a dependency of the `IndexModel` class: ```csharp public class IndexModel : PageModel { MyDependency _dependency = new MyDependency(); public async Task OnGetAsync() { await _dependency.WriteMessage( "IndexModel.OnGetAsync created this message."); } } ``` ::: moniker-end ::: moniker range="<= aspnetcore-2.0" An instance of the `MyDependency` class can be created to make the `WriteMessage` method available to a class. The `MyDependency` class is a dependency of the `HomeController` class: ```csharp public class HomeController : Controller { MyDependency _dependency = new MyDependency(); public async Task Index() { await _dependency.WriteMessage( "HomeController.Index created this message."); return View(); } } ``` ::: moniker-end The class creates and directly depends on the `MyDependency` instance. Code dependencies (such as the previous example) are problematic and should be avoided for the following reasons: * To replace `MyDependency` with a different implementation, the class must be modified. * If `MyDependency` has dependencies, they must be configured by the 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. The app should use a mock or stub `MyDependency` class, which isn't possible with this approach. Dependency injection addresses these problems through: * The use of an interface to abstract the dependency implementation. * Registration of the dependency in a service container. ASP.NET Core provides a built-in service container, [IServiceProvider](/dotnet/api/system.iserviceprovider). Services are registered in the app's `Startup.ConfigureServices` method. * *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/aspnet/Docs/tree/master/aspnetcore/fundamentals/dependency-injection/samples), the `IMyDependency` interface defines a method that the service provides to the app: ::: moniker range=">= aspnetcore-2.1" [!code-csharp[](dependency-injection/samples/2.x/DependencyInjectionSample/Interfaces/IMyDependency.cs?name=snippet1)] ::: moniker-end ::: moniker range="<= aspnetcore-2.0" [!code-csharp[](dependency-injection/samples/1.x/DependencyInjectionSample/Interfaces/IMyDependency.cs?name=snippet1)] ::: moniker-end This interface is implemented by a concrete type, `MyDependency`: ::: moniker range=">= aspnetcore-2.1" [!code-csharp[](dependency-injection/samples/2.x/DependencyInjectionSample/Services/MyDependency.cs?name=snippet1)] ::: moniker-end ::: moniker range="<= aspnetcore-2.0" [!code-csharp[](dependency-injection/samples/1.x/DependencyInjectionSample/Services/MyDependency.cs?name=snippet1)] ::: moniker-end `MyDependency` requests an [ILogger<TCategoryName>](/dotnet/api/microsoft.extensions.logging.ilogger-1) in its constructor. 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*. `IMyDependency` and `ILogger` must be registered in the service container. `IMyDependency` is registered in `Startup.ConfigureServices`. `ILogger` is registered by the logging abstractions infrastructure, so it's a [framework-provided service](#framework-provided-services) registered by default by the framework. In the sample app, the `IMyDependency` service is registered with the concrete type `MyDependency`. The registration scopes the service lifetime to the lifetime of a single request. [Service lifetimes](#service-lifetimes) are described later in this topic. ::: moniker range=">= aspnetcore-2.1" [!code-csharp[](dependency-injection/samples/2.x/DependencyInjectionSample/Startup.cs?name=snippet1&highlight=11)] ::: moniker-end ::: moniker range="<= aspnetcore-2.0" [!code-csharp[](dependency-injection/samples/1.x/DependencyInjectionSample/Startup.cs?name=snippet1&highlight=5)] ::: moniker-end > [!NOTE] > Each `services.Add{SERVICE_NAME}` extension method adds (and potentially configures) services. For example, `services.AddMvc()` adds the services Razor Pages and MVC require. We recommended that apps follow this convention. Place extension methods in the [Microsoft.Extensions.DependencyInjection](/dotnet/api/microsoft.extensions.dependencyinjection) namespace to encapsulate groups of service registrations. If the service's constructor requires a primitive, such as a `string`, the primitive can be injected by using [configuration](xref:fundamentals/configuration/index) or the [options pattern](xref:fundamentals/configuration/options): ```csharp public class MyDependency : IMyDependency { public MyDependency(IConfiguration config) { var myStringValue = config["MyStringKey"]; // Use myStringValue } ... } ``` An instance of the service is requested via the constructor of a class where the service is used and assigned to a private field. The field is used to access the service as necessary throughout the class. In the sample app, the `IMyDependency` instance is requested and used to call the service's `WriteMessage` method: ::: moniker range=">= aspnetcore-2.1" [!code-csharp[](dependency-injection/samples/2.x/DependencyInjectionSample/Pages/Index.cshtml.cs?name=snippet1&highlight=3,6,13,29-30)] ::: moniker-end ::: moniker range="<= aspnetcore-2.0" [!code-csharp[](dependency-injection/samples/1.x/DependencyInjectionSample/Controllers/MyDependencyController.cs?name=snippet1&highlight=3,5-8,13-14)] ::: moniker-end ## Framework-provided services The `Startup.ConfigureServices` method is responsible for defining the services the app uses, including platform features, such as Entity Framework Core and ASP.NET Core MVC. Initially, the `IServiceCollection` provided to `ConfigureServices` has the following services defined (depending on [how the host was configured](xref:fundamentals/host/index)): | Service Type | Lifetime | | ------------ | -------- | | [Microsoft.AspNetCore.Hosting.Builder.IApplicationBuilderFactory](/dotnet/api/microsoft.aspnetcore.hosting.builder.iapplicationbuilderfactory) | Transient | | [Microsoft.AspNetCore.Hosting.IApplicationLifetime](/dotnet/api/microsoft.aspnetcore.hosting.iapplicationlifetime) | Singleton | | [Microsoft.AspNetCore.Hosting.IHostingEnvironment](/dotnet/api/microsoft.aspnetcore.hosting.ihostingenvironment) | Singleton | | [Microsoft.AspNetCore.Hosting.IStartup](/dotnet/api/microsoft.aspnetcore.hosting.istartup) | Singleton | | [Microsoft.AspNetCore.Hosting.IStartupFilter](/dotnet/api/microsoft.aspnetcore.hosting.istartupfilter) | Transient | | [Microsoft.AspNetCore.Hosting.Server.IServer](/dotnet/api/microsoft.aspnetcore.hosting.server.iserver) | Singleton | | [Microsoft.AspNetCore.Http.IHttpContextFactory](/dotnet/api/microsoft.aspnetcore.http.ihttpcontextfactory) | Transient | | [Microsoft.Extensions.Logging.ILogger<T>](/dotnet/api/microsoft.extensions.logging.ilogger) | Singleton | | [Microsoft.Extensions.Logging.ILoggerFactory](/dotnet/api/microsoft.extensions.logging.iloggerfactory) | Singleton | | [Microsoft.Extensions.ObjectPool.ObjectPoolProvider](/dotnet/api/microsoft.extensions.objectpool.objectpoolprovider) | Singleton | | [Microsoft.Extensions.Options.IConfigureOptions<T>](/dotnet/api/microsoft.extensions.options.iconfigureoptions-1) | Transient | | [Microsoft.Extensions.Options.IOptions<T>](/dotnet/api/microsoft.extensions.options.ioptions-1) | Singleton | | [System.Diagnostics.DiagnosticSource](https://docs.microsoft.com/dotnet/core/api/system.diagnostics.diagnosticsource) | Singleton | | [System.Diagnostics.DiagnosticListener](https://docs.microsoft.com/dotnet/core/api/system.diagnostics.diagnosticlistener) | Singleton | When a service collection extension method is available to register a service (and its dependent services, if required), the convention is to use a single `Add{SERVICE_NAME}` extension method to register all of the services required by that service. The following code is an example of how to add additional services to the container using the extension methods [AddDbContext](/dotnet/api/microsoft.extensions.dependencyinjection.entityframeworkservicecollectionextensions.adddbcontext), [AddIdentity](/dotnet/api/microsoft.extensions.dependencyinjection.identityservicecollectionextensions.addidentity), and [AddMvc](/dotnet/api/microsoft.extensions.dependencyinjection.mvcservicecollectionextensions.addmvc): ```csharp public void ConfigureServices(IServiceCollection services) { services.AddDbContext(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddIdentity() .AddEntityFrameworkStores() .AddDefaultTokenProviders(); services.AddMvc(); } ``` For more information, see the [ServiceCollection Class](/dotnet/api/microsoft.extensions.dependencyinjection.servicecollection) in the API documentation. ## Service lifetimes Choose an appropriate lifetime for each registered service. ASP.NET Core services can be configured with the following lifetimes: **Transient** Transient lifetime services are created each time they're requested. This lifetime works best for lightweight, stateless services. **Scoped** Scoped lifetime services are created once per request. > [!WARNING] > When using a scoped service in a middleware, inject the service into the `Invoke` or `InvokeAsync` method. Don't inject via constructor injection because it forces the service to behave like a singleton. For more information, see . **Singleton** Singleton lifetime services are created the first time they're requested (or when `ConfigureServices` is run and an instance is specified with the service registration). Every subsequent request uses the same instance. If the app requires singleton behavior, allowing the service container to manage the service's lifetime is recommended. Don't implement the singleton design pattern and provide user code to manage the object's lifetime in the class. > [!WARNING] > It's dangerous to resolve a scoped service from a singleton. It may cause the service to have incorrect state when processing subsequent requests. ### Constructor injection behavior Services can be resolved by two mechanisms: * `IServiceProvider` * [ActivatorUtilities](/dotnet/api/microsoft.extensions.dependencyinjection.activatorutilities) – Permits object creation without service registration in the dependency injection container. `ActivatorUtilities` is used with user-facing abstractions, such as Tag Helpers, MVC controllers, and model binders. Constructors can accept arguments that aren't provided by dependency injection, but the arguments must assign default values. When services are resolved by `IServiceProvider` or `ActivatorUtilities`, constructor injection requires a *public* constructor. When services are resolved by `ActivatorUtilities`, constructor injection requires that only one applicable constructor exist. Constructor overloads are supported, but only one overload can exist whose arguments can all be fulfilled by dependency injection. ## Entity Framework contexts Entity Framework contexts should be added to the service container using the scoped lifetime. This is handled automatically with a call to the [AddDbContext](/dotnet/api/microsoft.extensions.dependencyinjection.entityframeworkservicecollectionextensions.adddbcontext) method when registering the database context. Services that use the database context should also use the scoped lifetime. ## Lifetime and registration options To demonstrate the difference between the lifetime and registration options, consider the following interfaces that represent tasks as an operation with a unique identifier, `OperationId`. Depending on how the lifetime of an operations service is configured for the following interfaces, the container provides either the same or a different instance of the service when requested by a class: ::: moniker range=">= aspnetcore-2.1" [!code-csharp[](dependency-injection/samples/2.x/DependencyInjectionSample/Interfaces/IOperation.cs?name=snippet1)] ::: moniker-end ::: moniker range="<= aspnetcore-2.0" [!code-csharp[](dependency-injection/samples/1.x/DependencyInjectionSample/Interfaces/IOperation.cs?name=snippet1)] ::: moniker-end The interfaces are implemented in the `Operation` class. The `Operation` constructor generates a GUID if one isn't supplied: ::: moniker range=">= aspnetcore-2.1" [!code-csharp[](dependency-injection/samples/2.x/DependencyInjectionSample/Models/Operation.cs?name=snippet1)] ::: moniker-end ::: moniker range="<= aspnetcore-2.0" [!code-csharp[](dependency-injection/samples/1.x/DependencyInjectionSample/Models/Operation.cs?name=snippet1)] ::: moniker-end An `OperationService` is registered that depends on each of the other `Operation` types. When `OperationService` is requested via dependency injection, it receives either a new instance of each service or an existing instance based on the lifetime of the dependent service. * If transient services are created when requested, the `OperationsId` of the `IOperationTransient` service is different than the `OperationsId` of the `OperationService`. `OperationService` receives a new instance of the `IOperationTransient` class. The new instance yields a different `OperationsId`. * If scoped services are created per request, the `OperationsId` of the `IOperationScoped` service is the same as that of `OperationService` within a request. Across requests, both services share a different `OperationsId` value. * If singleton and singleton-instance services are created once and used across all requests and all services, the `OperationsId` is constant across all service requests. ::: moniker range=">= aspnetcore-2.1" [!code-csharp[](dependency-injection/samples/2.x/DependencyInjectionSample/Services/OperationService.cs?name=snippet1)] ::: moniker-end ::: moniker range="<= aspnetcore-2.0" [!code-csharp[](dependency-injection/samples/1.x/DependencyInjectionSample/Services/OperationService.cs?name=snippet1)] ::: moniker-end In `Startup.ConfigureServices`, each type is added to the container according to its named lifetime: ::: moniker range=">= aspnetcore-2.1" [!code-csharp[](dependency-injection/samples/2.x/DependencyInjectionSample/Startup.cs?name=snippet1&highlight=12-15,18)] ::: moniker-end ::: moniker range="<= aspnetcore-2.0" [!code-csharp[](dependency-injection/samples/1.x/DependencyInjectionSample/Startup.cs?name=snippet1&highlight=6-9,12)] ::: moniker-end The `IOperationSingletonInstance` service is using a specific instance with a known ID of `Guid.Empty`. It's clear when this type is in use (its GUID is all zeroes). ::: moniker range=">= aspnetcore-2.1" The sample app demonstrates object lifetimes within and between individual requests. The sample app's `IndexModel` requests each kind of `IOperation` type and the `OperationService`. The page then displays all of the page model class's and service's `OperationId` values through property assignments: [!code-csharp[](dependency-injection/samples/2.x/DependencyInjectionSample/Pages/Index.cshtml.cs?name=snippet1&highlight=7-11,14-18,21-25)] ::: moniker-end ::: moniker range="<= aspnetcore-2.0" The sample app demonstrates object lifetimes within and between individual requests. The sample app includes an `OperationsController` that requests each kind of `IOperation` type and the `OperationService`. The `Index` action sets the services into the `ViewBag` for display of the service's `OperationId` values: [!code-csharp[](dependency-injection/samples/1.x/DependencyInjectionSample/Controllers/OperationsController.cs?name=snippet1)] ::: moniker-end Two following output shows the results of two requests: **First request:** Controller operations: Transient: d233e165-f417-469b-a866-1cf1935d2518 Scoped: 5d997e2d-55f5-4a64-8388-51c4e3a1ad19 Singleton: 01271bc1-9e31-48e7-8f7c-7261b040ded9 Instance: 00000000-0000-0000-0000-000000000000 `OperationService` operations: Transient: c6b049eb-1318-4e31-90f1-eb2dd849ff64 Scoped: 5d997e2d-55f5-4a64-8388-51c4e3a1ad19 Singleton: 01271bc1-9e31-48e7-8f7c-7261b040ded9 Instance: 00000000-0000-0000-0000-000000000000 **Second request:** Controller operations: Transient: b63bd538-0a37-4ff1-90ba-081c5138dda0 Scoped: 31e820c5-4834-4d22-83fc-a60118acb9f4 Singleton: 01271bc1-9e31-48e7-8f7c-7261b040ded9 Instance: 00000000-0000-0000-0000-000000000000 `OperationService` operations: Transient: c4cbacb8-36a2-436d-81c8-8c1b78808aaf Scoped: 31e820c5-4834-4d22-83fc-a60118acb9f4 Singleton: 01271bc1-9e31-48e7-8f7c-7261b040ded9 Instance: 00000000-0000-0000-0000-000000000000 Observe which of the `OperationId` values vary within a request and between requests: * *Transient* objects are always different. Note that the transient `OperationId` value for both the first and second requests are different for both `OperationService` operations and across requests. A new instance is provided to each service and request. * *Scoped* objects are the same within a request but different across requests. * *Singleton* objects are the same for every object and every request regardless of whether an `Operation` instance is provided in `ConfigureServices`. ## Call services from main Create an [IServiceScope](/dotnet/api/microsoft.extensions.dependencyinjection.iservicescope) with [IServiceScopeFactory.CreateScope](/dotnet/api/microsoft.extensions.dependencyinjection.iservicescopefactory.createscope) to resolve a scoped service within the app's scope. This approach is useful to access a scoped service at startup to run initialization tasks. The following example shows how to obtain a context for the `MyScopedService` in `Program.Main`: ```csharp public static void Main(string[] args) { var host = CreateWebHostBuilder(args).Build(); using (var serviceScope = host.Services.CreateScope()) { var services = serviceScope.ServiceProvider; try { var serviceContext = services.GetRequiredService(); // Use the context here } catch (Exception ex) { var logger = services.GetRequiredService>(); logger.LogError(ex, "An error occurred."); } } host.Run(); } ``` ## Scope validation ::: moniker range=">= aspnetcore-2.0" When the app is running in the Development environment, the default service provider performs checks to verify that: * Scoped services aren't directly or indirectly resolved from the root service provider. * Scoped services aren't directly or indirectly injected into singletons. ::: moniker-end The root service provider is created when [BuildServiceProvider](/dotnet/api/microsoft.extensions.dependencyinjection.servicecollectioncontainerbuilderextensions.buildserviceprovider) is called. The root service provider's lifetime corresponds to the app/server's lifetime when the provider starts with the app and is disposed when the app shuts down. Scoped services are disposed by the container that created them. If a scoped service is created in the root container, the service's lifetime is effectively promoted to singleton because it's only disposed by the root container when app/server is shut down. Validating service scopes catches these situations when `BuildServiceProvider` is called. For more information, see . ## Request Services The services available within an ASP.NET Core request from `HttpContext` are exposed through the [HttpContext.RequestServices](/dotnet/api/microsoft.aspnetcore.http.httpcontext.requestservices) collection. Request Services represent the services configured and requested as part of the app. When the objects specify dependencies, these are satisfied by the types found in `RequestServices`, not `ApplicationServices`. Generally, the app shouldn't use these properties directly. Instead, request the types that classes require via class constructors and allow the framework inject the dependencies. This yields classes that are easier to test (see the [Test and debug](xref:test/index) topics). > [!NOTE] > Prefer requesting dependencies as constructor parameters to accessing the `RequestServices` collection. ## Design services for dependency injection Best practices are to: * Design services to use dependency injection to obtain their dependencies. * Avoid stateful, static method calls (a practice known as [static cling](https://deviq.com/static-cling/)). * Avoid direct instantiation of dependent classes within services. Direct instantiation couples the code to a particular implementation. By following the [SOLID Principles of Object Oriented Design](https://deviq.com/solid/), app classes naturally tend to be small, well-factored, and easily tested. If a class seems to have too many injected dependencies, this is generally a sign that the class has too many responsibilities and is violating the [Single Responsibility Principle (SRP)](https://deviq.com/single-responsibility-principle/). Attempt to refactor the class by moving some of its responsibilities into a new class. Keep in mind that Razor Pages page model classes and MVC controller classes should focus on UI concerns. Business rules and data access implementation details should be kept in classes appropriate to these [separate concerns](https://deviq.com/separation-of-concerns/). ### Disposal of services The container calls `Dispose` for the `IDisposable` types it creates. If an instance is added to the container by user code, it isn't disposed automatically. ```csharp // Services that implement IDisposable: public class Service1 : IDisposable {} public class Service2 : IDisposable {} public class Service3 : IDisposable {} public interface ISomeService {} public class SomeServiceImplementation : ISomeService, IDisposable {} public void ConfigureServices(IServiceCollection services) { // The container creates the following instances and disposes them automatically: services.AddScoped(); services.AddSingleton(); services.AddSingleton(sp => new SomeServiceImplementation()); // The container doesn't create the following instances, so it doesn't dispose of // the instances automatically: services.AddSingleton(new Service3()); services.AddSingleton(new Service3()); } ``` ::: moniker range="= aspnetcore-1.0" > [!NOTE] > In ASP.NET Core 1.0, the container calls dispose on *all* `IDisposable` objects, including those it didn't create. ::: moniker-end ## Default service container replacement The built-in service container is meant to serve the needs of the framework and most consumer apps. We recommend using the built-in container unless you need a specific feature that it doesn't support. Some of the features supported in 3rd party containers not found in the built-in container: * Property injection * Injection based on name * Child containers * Custom lifetime management * `Func` support for lazy initialization See the [Dependency Injection readme.md file](https://github.com/aspnet/DependencyInjection#using-other-containers-with-microsoftextensionsdependencyinjection) for a list of some of the containers that support adapters. The following sample replaces the built-in container with [Autofac](https://autofac.org/): * Install the appropriate container package(s): * [Autofac](https://www.nuget.org/packages/Autofac/) * [Autofac.Extensions.DependencyInjection](https://www.nuget.org/packages/Autofac.Extensions.DependencyInjection/) * Configure the container in `Startup.ConfigureServices` and return an `IServiceProvider`: ```csharp public IServiceProvider ConfigureServices(IServiceCollection services) { services.AddMvc(); // Add other framework services // Add Autofac var containerBuilder = new ContainerBuilder(); containerBuilder.RegisterModule(); containerBuilder.Populate(services); var container = containerBuilder.Build(); return new AutofacServiceProvider(container); } ``` To use a 3rd party container, `Startup.ConfigureServices` must return `IServiceProvider`. * Configure Autofac in `DefaultModule`: ```csharp public class DefaultModule : Module { protected override void Load(ContainerBuilder builder) { builder.RegisterType().As(); } } ``` At runtime, Autofac is used to resolve types and inject dependencies. To learn more about using Autofac with ASP.NET Core, see the [Autofac documentation](https://docs.autofac.org/en/latest/integration/aspnetcore.html). ### Thread safety Singleton services need to be thread safe. If a singleton service has a dependency on a transient service, the transient service may also need to be thread safe depending how it's used by the singleton. The factory method of single service, such as the second argument to [AddSingleton<TService>(IServiceCollection, Func<IServiceProvider,TService>)](/dotnet/api/microsoft.extensions.dependencyinjection.servicecollectionserviceextensions.addsingleton#Microsoft_Extensions_DependencyInjection_ServiceCollectionServiceExtensions_AddSingleton__1_Microsoft_Extensions_DependencyInjection_IServiceCollection_System_Func_System_IServiceProvider___0__), doesn't need to be thread-safe. Like a type (`static`) constructor, it's guaranteed to be called once by a single thread. ## Recommendations When working with dependency injection, keep the following recommendations in mind: * Avoid storing data and configuration directly in the service container. For example, a user's shopping cart shouldn't typically be added to the service container. Configuration should use the [options pattern](xref:fundamentals/configuration/options). Similarly, avoid "data holder" objects that only exist to allow access to some other object. It's better to request the actual item via dependency injection, if possible. * Avoid static access to services (for example, statically-typing [IApplicationBuilder.ApplicationServices](/dotnet/api/microsoft.aspnetcore.builder.iapplicationbuilder.applicationservices) for use elsewhere). * Avoid using the service locator pattern (for example, [IServiceProvider.GetService](/dotnet/api/system.iserviceprovider.getservice)). * Avoid static access to `HttpContext` (for example, [IHttpContextAccessor.HttpContext](/dotnet/api/microsoft.aspnetcore.http.ihttpcontextaccessor.httpcontext)). Like all sets of recommendations, you may encounter situations where ignoring a recommendation is required. Exceptions are rare—mostly special cases within the framework itself. Dependency injection is an *alternative* to static/global object access patterns. You may not be able to realize the benefits of dependency injection if you mix it with static object access. ## Additional resources * * * * * * * * [Writing Clean Code in ASP.NET Core with Dependency Injection (MSDN)](https://msdn.microsoft.com/magazine/mt703433.aspx) * [Container-Managed Application Design, Prelude: Where does the Container Belong?](https://blogs.msdn.microsoft.com/nblumhardt/2008/12/26/container-managed-application-design-prelude-where-does-the-container-belong/) * [Explicit Dependencies Principle](https://deviq.com/explicit-dependencies-principle/) * [Inversion of Control Containers and the Dependency Injection Pattern (Martin Fowler)](https://www.martinfowler.com/articles/injection.html) * [New is Glue ("gluing" code to a particular implementation)](https://ardalis.com/new-is-glue)