ASP.NET Core 控制器的相依性插入

作者:Shadi NamroutiRick AndersonSteve Smith

ASP.NET Core MVC 控制器會透過建構函式明確地要求相依性。 ASP.NET Core 內建相依性插入 (DI) 支援。 DI 可讓您更輕鬆地測試和維護應用程式。

查看或下載範例程式碼 (如何下載)

建構函式插入

服務會新增來作為建構函式參數,而執行階段會解析來自服務容器的服務。 通常可以使用介面來定義服務。 例如,假設應用程式需要目前的時間。 下列介面會公開 IDateTime 服務:

public interface IDateTime
{
    DateTime Now { get; }
}

下列程式碼會實作 IDateTime 介面:

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

將服務新增至服務容器:

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

    services.AddControllersWithViews();
}

如需 AddSingleton 的詳細資訊,請參閱 DI 服務存留期

下列程式碼會根據時段來向使用者顯示問候語:

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();
    }

執行應用程式,並根據時間顯示訊息。

使用 FromServices 進行動作插入

FromServicesAttribute 能夠將服務直接插入至動作方法,而不需使用建構函式插入:

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

從控制器存取設定

從控制器存取應用程式或組態設定是常見的模式。 ASP.NET Core 中的選項模式 中所述的「選項模式」是管理設定的慣用方法。 一般而言,不要將 IConfiguration 直接插入至控制器。

建立要代表選項的類別。 例如:

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

將設定類別新增至服務集合:

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

    services.AddControllersWithViews();
}

設定應用程式以從 JSON 格式的檔案中讀取設定:

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 方法中使用它們:

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();
    }
}

其他資源

作者:Shadi NamroutiRick AndersonSteve Smith

ASP.NET Core MVC 控制器會透過建構函式明確地要求相依性。 ASP.NET Core 內建相依性插入 (DI) 支援。 DI 可讓您更輕鬆地測試和維護應用程式。

查看或下載範例程式碼 (如何下載)

建構函式插入

服務會新增來作為建構函式參數,而執行階段會解析來自服務容器的服務。 通常可以使用介面來定義服務。 例如,假設應用程式需要目前的時間。 下列介面會公開 IDateTime 服務:

public interface IDateTime
{
    DateTime Now { get; }
}

下列程式碼會實作 IDateTime 介面:

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

將服務新增至服務容器:

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

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

如需 AddSingleton 的詳細資訊,請參閱 DI 服務存留期

下列程式碼會根據時段來向使用者顯示問候語:

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();
    }

執行應用程式,並根據時間顯示訊息。

使用 FromServices 進行動作插入

FromServicesAttribute 能夠將服務直接插入至動作方法,而不需使用建構函式插入:

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

    return View();
}

從控制器存取設定

從控制器存取應用程式或組態設定是常見的模式。 ASP.NET Core 中的選項模式 中所述的「選項模式」是管理設定的慣用方法。 一般而言,不要將 IConfiguration 直接插入至控制器。

建立要代表選項的類別。 例如:

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

將設定類別新增至服務集合:

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

設定應用程式以從 JSON 格式的檔案中讀取設定:

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 方法中使用它們:

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();
    }
}

其他資源