ASP.NET Core MVCの依存注入Controller

11041 ワード

ASP.NET Core MVCコントローラは、コンストラクション関数によって依存関係を明確に要求する必要があります.場合によっては、単一のコントローラの動作にサービスが必要になり、コントローラレベルでの要求に意味がない場合があります.この場合、サービスをActionのパラメータとしてもよい.
依存注入は、アプリケーションがばらばらに結合されたモジュール構成を可能にするDependency Inversion Principleに示す技術である.
1.コンストラクタ注入
  ASP.NET Coreに内蔵されたコンストラクション関数に基づく依存注入サポートはMVCコントローラに拡張されている.コンストラクション関数パラメータとして1つのサービスタイプのみをコントローラに追加することにより、ASP.NET Coreは、このタイプを内蔵サービスコンテナで解析しようとします.サービスは、通常(ただし、必ずしも)インタフェース定義を使用します.たとえば、アプリケーションが取得時間のサービスを定義し、ハードコーディングではなく注入に依存する場合:
インタフェースとインプリメンテーションの定義:
namespace MVCTest.Services
{
    public interface IDateTime
    {
        DateTime Now { get; }
    }
    public class SystemDateTime: IDateTime
    {
        public DateTime Now
        {
            get { return DateTime.Now; }
        }
    }
}

コンフィギュレーションサービスでコンテナにサービスを登録するには、次の手順に従います.
services.AddTransient();

コントロールで使用:
    public class DateTimeController : Controller
    {
        private IDateTime _dateTime;
        public DateTimeController(IDateTime dateTime)
        {
            _dateTime = dateTime;
        }
        // GET: DateTime
        public ActionResult Index()
        {
            var serverTime = _dateTime.Now;
            if (serverTime.Hour < 12)
            {
                ViewData["Message"] = "Good Morning";
            }
            return View();
        }
}

  ASP.NET Coreに組み込まれた依存注入サポートは、サービスを要求するタイプに1つのコンストラクション関数しかありません.1つ以上ある場合、例外が報告されます.サードパーティ製インプリメンテーションを使用して、デフォルトの依存注入を置き換え、複数のコンストラクション関数をサポートすることができます.
 
2.FromServices操作による注入
コントローラで複数の操作にサービスを提供する必要がない場合があります.この場合,動作方法のパラメータにサービスを注入することは有意義である.[FromServices]タグパラメータによって実現されます.
        public ActionResult Index([FromServices] IDateTime _dateTime)
        {
            var serverTime = _dateTime.Now;
            if (serverTime.Hour < 12)
            {
                ViewData["Message"] = "Good Morning";
            }
            return View();
        }

 
3.コントローラでのアクセス設定
コントローラでアプリケーションの設定や設定にアクセスするときによくあるモードです.このアクセスは、コンフィギュレーションで説明したアクセスモードを使用する必要があります.通常、コントローラから依存注入直接要求設定を使用するべきではありません.より良い方法は、IOptionsインスタンスを要求することです.Tは必要な構成タイプです.例:
オプションクラスを作成するには
public class AppSettingOptions
    {
        public DefaultConnec ConnectionStrings { get; set; }
        public string AllowedHosts { get; set; }
    }

    public class DefaultConnec
    {
        public string DefaultConnection { get; set; }
    }

appsettings.json:
{
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=.;Initial Catalog=Test;Integrated Security=True"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information"
    }
  },
  "AllowedHosts": "*"
}

コンフィギュレーション・アプリケーションでは、オプション・モデルを使用してコンフィギュレーション・クラスをコンフィギュレーション・コンテナに追加します.
public Startup(IConfiguration configuration,IHostingEnvironment env)
        {
            //Configuration = configuration;
            var builder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json",optional:true,reloadOnChange:true)
                //.AddJsonFile($"appsettings.{env.EnvironmentName}.json",optional:true)
                ;

            //      
            //builder.AddEnvironmentVariables();
            Configuration = builder.Build();
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddOptions();
            services.Configure(Configuration);
            //      
            services.Configure(options=>
            {
                options.AllowedHosts = "test";
            });
        }

例はappsettings.jsonは設定を読み込み、コードに設定を追加することもできます.
要求タイプのコンフィギュレーションオブジェクトAppSettings Optionsを指定してサービスコンテナに追加すると、コントローラまたは操作方法でIOptionsのインスタンスを要求して取得できます.
    public class HomeController : Controller
    {
        private readonly IOptions _options;
        public HomeController(IOptions options)
        {
            _options = options;
        }
}

オプションモードに従うと、設定と構成を分離できます.また、コントローラが設定情報をどこで見つけるかを知る必要がないため、注目点の分離に従うことを確認します.コントローラクラスには静的アタッチや直接インスタンス化設定クラスがないため、コントローラはユニットテストをより容易に使用できます.