Back to Aspnetcore

Dependency Injection7

aspnetcore/mvc/controllers/includes/dependency-injection7.md

latest9.2 KB
Original Source

:::moniker range=">= aspnetcore-3.0 < aspnetcore-8.0"

By Rick Anderson and Steve Smith

ASP.NET Core MVC controllers request dependencies explicitly via constructors. ASP.NET Core has built-in support for dependency injection (DI). DI makes apps easier to test and maintain.

View or download sample code (how to download)

Constructor injection

Services are added as a constructor parameter, and the runtime resolves the service from the service container. Services are typically defined using interfaces. For example, consider an app that requires the current time. The following interface exposes the IDateTime service:

[!code-csharp]

The following code implements the IDateTime interface:

[!code-csharp]

Add the service to the service container:

[!code-csharp]

For more information on xref:Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton*, see DI service lifetimes.

The following code displays a greeting to the user based on the time of day:

[!code-csharp]

Run the app and a message is displayed based on the time.

Action injection with FromServices

The xref:Microsoft.AspNetCore.Mvc.FromServicesAttribute enables injecting a service directly into an action method without using constructor injection:

[!code-csharp]

Access settings from a controller

Accessing app or configuration settings from within a controller is a common pattern. The options pattern described in xref:fundamentals/configuration/options is the preferred approach to manage settings. Generally, don't directly inject xref:Microsoft.Extensions.Configuration.IConfiguration into a controller.

Create a class that represents the options. For example:

[!code-csharp]

Add the configuration class to the services collection:

[!code-csharp]

Configure the app to read the settings from a JSON-formatted file:

[!code-csharp]

The following code requests the IOptions<SampleWebSettings> settings from the service container and uses them in the Index method:

[!code-csharp]

Controllers as services

By default, ASP.NET Core doesn't register controllers as services in the DI container. The runtime uses the DefaultControllerActivator to create controller instances and resolves services from the DI container for constructor parameters, but the controller itself isn't resolved from the container.

Calling AddControllersAsServices registers all controllers as services in the DI container:

csharp
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews().AddControllersAsServices();
}

Registering controllers as services enables:

  • Intercepting controller creation with a custom IControllerActivator.
  • Using any DI lifetime management for controllers.
  • Injecting services into controllers using any registered constructor, since the DI container selects the constructor.

[!NOTE] Configure the ApplicationPartManager before calling AddControllersAsServices. See xref:mvc/extensibility/app-parts#prevent-loading-resources for details.

Additional resources

:::moniker-end

:::moniker range="< aspnetcore-3.0"

ASP.NET Core MVC controllers request dependencies explicitly via constructors. ASP.NET Core has built-in support for dependency injection (DI). DI makes apps easier to test and maintain.

View or download sample code (how to download)

Constructor injection

Services are added as a constructor parameter, and the runtime resolves the service from the service container. Services are typically defined using interfaces. For example, consider an app that requires the current time. The following interface exposes the IDateTime service:

[!code-csharp]

The following code implements the IDateTime interface:

[!code-csharp]

Add the service to the service container:

[!code-csharp]

For more information on xref:Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddSingleton*, see DI service lifetimes.

The following code displays a greeting to the user based on the time of day:

[!code-csharp]

Run the app and a message is displayed based on the time.

Action injection with FromServices

The xref:Microsoft.AspNetCore.Mvc.FromServicesAttribute enables injecting a service directly into an action method without using constructor injection:

[!code-csharp]

Access settings from a controller

Accessing app or configuration settings from within a controller is a common pattern. The options pattern described in xref:fundamentals/configuration/options is the preferred approach to manage settings. Generally, don't directly inject xref:Microsoft.Extensions.Configuration.IConfiguration into a controller.

Create a class that represents the options. For example:

[!code-csharp]

Add the configuration class to the services collection:

[!code-csharp]

Configure the app to read the settings from a JSON-formatted file:

[!code-csharp]

The following code requests the IOptions<SampleWebSettings> settings from the service container and uses them in the Index method:

[!code-csharp]

Controllers as services

By default, ASP.NET Core doesn't register controllers as services in the DI container. The runtime uses the DefaultControllerActivator to create controller instances and resolves services from the DI container for constructor parameters, but the controller itself isn't resolved from the container.

Calling AddControllersAsServices registers all controllers as services in the DI container:

csharp
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().AddControllersAsServices();
}

Registering controllers as services enables:

  • Intercepting controller creation with a custom IControllerActivator.
  • Using any DI lifetime management for controllers.
  • Injecting services into controllers using any registered constructor, since the DI container selects the constructor.

[!NOTE] Configure the ApplicationPartManager before calling AddControllersAsServices. See xref:mvc/extensibility/app-parts#prevent-loading-resources for details.

Additional resources

:::moniker-end