在 ASP.NET Core 中将依赖项注入到控制器Dependency injection into controllers in ASP.NET Core

作者:Shadi NamroutiRick AndersonSteve SmithBy 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 使应用更易于测试和维护。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 的详细信息,请参阅 DI 服务生存期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.

FromServices 的操作注入Action 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 NamroutiRick AndersonSteve SmithBy 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 使应用更易于测试和维护。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 的详细信息,请参阅 DI 服务生存期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.

FromServices 的操作注入Action 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