Внедрение зависимостей в контроллеры в ASP.NET CoreDependency injection into controllers in ASP.NET Core

Авторы: Shadi Namrouti (Шади Намрути), Рик Андерсон (Rick Anderson) и Стив Смит (Steve Smith)By Shadi Namrouti, Rick Anderson, and Steve Smith

Контроллеры ASP.NET Core MVC запрашивают зависимости явно с помощью конструкторов.ASP.NET Core MVC controllers request dependencies explicitly via constructors. ASP.NET Core имеет встроенную поддержку внедрения зависимостей (DI).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. Следующие интерфейсы предоставляют службу IDateTime:The following interface exposes the IDateTime service:

public interface IDateTime
{
    DateTime Now { get; }
}

В следующем коде реализуется интерфейс IDateTime:The following code implements the IDateTime interface:

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

Добавьте службу в контейнер службы:Add the service to the service container:

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

    services.AddControllersWithViews();
}

Дополнительные сведения о AddSingleton, см. в разделе Время существования службы внедрения зависимости.For more information on AddSingleton, see DI service lifetimes.

Следующий код отображает приветствие пользователю в зависимости от времени дня: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();
    }

Запустите приложение, и в зависимости от времени отобразится сообщение.Run the app and a message is displayed based on the time.

Внедрение действий с помощью FromServicesAction injection with FromServices

FromServicesAttribute позволяет внедрять службу непосредственно в метод действия без использования внедрения через конструктор:The FromServicesAttribute enables injecting a service directly into an action method without using constructor injection:

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

Доступ к параметрам из контроллераAccess settings from a controller

Доступ к параметрам приложения или конфигурации из контроллера относится к типичным шаблонам.Accessing app or configuration settings from within a controller is a common pattern. Шаблон параметров, описанный в разделе Шаблон параметров в ASP.NET Core, является предпочтительным подходом для управления параметрами.The options pattern described in Шаблон параметров в ASP.NET Core is the preferred approach to manage settings. Как правило, не следует напрямую внедрять IConfiguration в контроллер.Generally, don't directly inject IConfiguration into a controller.

Создайте класс, представляющий параметры.Create a class that represents the options. Пример:For example:

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

Добавьте класс конфигурации в коллекцию служб:Add the configuration class to the services collection:

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

    services.AddControllersWithViews();
}

Настройте приложение для чтения параметров из файла формата JSON:Configure the app to read the settings from a JSON-formatted file:

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

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("samplewebsettings.json",
                    optional: false,
                    reloadOnChange: true);
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

Следующий код запрашивает параметры IOptions<SampleWebSettings> из контейнера служб и использует их в методе 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();
    }
}

Дополнительные ресурсыAdditional resources

Авторы: Shadi Namrouti (Шади Намрути), Рик Андерсон (Rick Anderson) и Стив Смит (Steve Smith)By Shadi Namrouti, Rick Anderson, and Steve Smith

Контроллеры ASP.NET Core MVC запрашивают зависимости явно с помощью конструкторов.ASP.NET Core MVC controllers request dependencies explicitly via constructors. ASP.NET Core имеет встроенную поддержку внедрения зависимостей (DI).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. Следующие интерфейсы предоставляют службу IDateTime:The following interface exposes the IDateTime service:

public interface IDateTime
{
    DateTime Now { get; }
}

В следующем коде реализуется интерфейс IDateTime:The following code implements the IDateTime interface:

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

Добавьте службу в контейнер службы:Add the service to the service container:

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

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

Дополнительные сведения о AddSingleton, см. в разделе Время существования службы внедрения зависимости.For more information on AddSingleton, see DI service lifetimes.

Следующий код отображает приветствие пользователю в зависимости от времени дня: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();
    }

Запустите приложение, и в зависимости от времени отобразится сообщение.Run the app and a message is displayed based on the time.

Внедрение действий с помощью FromServicesAction injection with FromServices

FromServicesAttribute позволяет внедрять службу непосредственно в метод действия без использования внедрения через конструктор: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();
}

Доступ к параметрам из контроллераAccess settings from a controller

Доступ к параметрам приложения или конфигурации из контроллера относится к типичным шаблонам.Accessing app or configuration settings from within a controller is a common pattern. Шаблон параметров, описанный в разделе Шаблон параметров в ASP.NET Core, является предпочтительным подходом для управления параметрами.The options pattern described in Шаблон параметров в ASP.NET Core is the preferred approach to manage settings. Как правило, не следует напрямую внедрять IConfiguration в контроллер.Generally, don't directly inject IConfiguration into a controller.

Создайте класс, представляющий параметры.Create a class that represents the options. Пример:For example:

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

Добавьте класс конфигурации в коллекцию служб: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);
}

Настройте приложение для чтения параметров из файла формата 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>();
}

Следующий код запрашивает параметры IOptions<SampleWebSettings> из контейнера служб и использует их в методе 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();
    }
}

Дополнительные ресурсыAdditional resources