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.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