Injeção de dependência em controladores no ASP.NET CoreDependency injection into controllers in ASP.NET Core

Por Shadi Namrouti, Rick Anderson e Steve SmithBy Shadi Namrouti, Rick Anderson, and Steve Smith

Controladores do ASP.NET Core MVC solicitam dependências explicitamente por meio de construtores.ASP.NET Core MVC controllers request dependencies explicitly via constructors. O ASP.NET Core tem suporte interno para DI (injeção de dependência).ASP.NET Core has built-in support for dependency injection (DI). A injeção de dependência torna mais fácil testar e manter aplicativos.DI makes apps easier to test and maintain.

Exibir ou baixar código de exemplo (como baixar)View or download sample code (how to download)

Injeção de construtorConstructor Injection

Os serviços são adicionados como um parâmetro de construtor e o tempo de execução resolve o serviço de contêiner de serviço.Services are added as a constructor parameter, and the runtime resolves the service from the service container. Os serviços são normalmente definidos usando interfaces.Services are typically defined using interfaces. Por exemplo, considere um aplicativo que exige a hora atual.For example, consider an app that requires the current time. A interface a seguir expõe o serviço IDateTime:The following interface exposes the IDateTime service:

public interface IDateTime
{
    DateTime Now { get; }
}

O código a seguir implementa a interface IDateTime:The following code implements the IDateTime interface:

public class SystemDateTime : IDateTime
{
    public DateTime Now
    {
        get { return DateTime.Now; }
    }
}

Adicione o serviço ao contêiner de serviço:Add the service to the service container:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IDateTime, SystemDateTime>();

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

Para obter mais informações sobre AddSingleton, veja tempos de vida do serviço DI.For more information on AddSingleton, see DI service lifetimes.

O código a seguir exibe uma saudação ao usuário com base na hora do dia:The following code displays a greeting to the user based on the time of day:

public class HomeController : Controller
{
    private readonly IDateTime _dateTime;

    public HomeController(IDateTime dateTime)
    {
        _dateTime = dateTime;
    }

    public IActionResult Index()
    {
        var serverTime = _dateTime.Now;
        if (serverTime.Hour < 12)
        {
            ViewData["Message"] = "It's morning here - Good Morning!";
        }
        else if (serverTime.Hour < 17)
        {
            ViewData["Message"] = "It's afternoon here - Good Afternoon!";
        }
        else
        {
            ViewData["Message"] = "It's evening here - Good Evening!";
        }
        return View();
    }

Execute o aplicativo e será exibida uma mensagem com base no horário.Run the app and a message is displayed based on the time.

Injeção de ação com FromServicesAction injection with FromServices

O FromServicesAttribute habilita a injeção de um serviço diretamente em um método de ação sem usar a injeção de construtor:The FromServicesAttribute enables injecting a service directly into an action method without using constructor injection:

public IActionResult About([FromServices] IDateTime dateTime)
{
    ViewData["Message"] = $"Current server time: {dateTime.Now}";

    return View();
}

Acessar configurações de um controladorAccess settings from a controller

Acessar definições de configuração ou do aplicativo de dentro de um controlador é um padrão comum.Accessing app or configuration settings from within a controller is a common pattern. O padrão de opções descrito em Padrão de opções no ASP.NET Core é a abordagem preferencial para gerenciar as configurações.The options pattern described in Padrão de opções no ASP.NET Core is the preferred approach to manage settings. Em geral, não convém injetar IConfiguration diretamente em um controlador.Generally, don't directly inject IConfiguration into a controller.

Crie uma classe que representa as opções.Create a class that represents the options. Por exemplo:For example:

public class SampleWebSettings
{
    public string Title { get; set; }
    public int Updates { get; set; }
}

Adicione a classe de configuração à coleção de serviços:Add the configuration class to the services collection:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IDateTime, SystemDateTime>();
    services.Configure<SampleWebSettings>(Configuration);
    
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

Configure o aplicativo para ler as configurações de um arquivo formatado em JSON:Configure the app to read the settings from a JSON-formatted file:

public class Program
{
    public static void Main(string[] args)
    {
        CreateWebHostBuilder(args).Build().Run();
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            config.AddJsonFile("samplewebsettings.json", 
                                optional: false,        // File is not optional.
                                reloadOnChange: false);
        })
        .UseStartup<Startup>();
}

O código a seguir solicita as configurações IOptions<SampleWebSettings> do contêiner de serviço e usa-as no método Index:The following code requests the IOptions<SampleWebSettings> settings from the service container and uses them in the Index method:

public class SettingsController : Controller
{
    private readonly SampleWebSettings _settings;

    public SettingsController(IOptions<SampleWebSettings> settingsOptions)
    {
        _settings = settingsOptions.Value;
    }

    public IActionResult Index()
    {
        ViewData["Title"] = _settings.Title;
        ViewData["Updates"] = _settings.Updates;
        return View();
    }
}

Recursos adicionaisAdditional resources