Asp.netコアを使用したサンプル例
録画ビデオリンク: https://www.youtube.com/watch?v=oVj1IHw8GLU
DI の概要: https://github.com/sandeepmvn/DependencyInjectionRepository/blob/master/OverviewOfDI.txt
ASP.NET Core は、クラスとその依存関係の間で制御の反転 (IoC) を実現するための技術である依存関係注入 (DI) ソフトウェア デザイン パターンをサポートしています。
IoC コンテナを通じて、次のことを実現できます。
Asp.net コアでは、IoC コンテナーにインターフェイスが組み込まれています。
次の DI ライフサイクルは次のようになります。
ASP.NET Core には基本的に 2 種類のサービスがあります。
フレームワーク サービス: IApplicationBuilder、IHostingEnvironment、ILoggerFactory などの ASP.NET Core フレームワークの一部であるサービス。
アプリケーション サービス: プログラマとしてアプリケーション用に作成するサービス (カスタム タイプまたはクラス)。
Asp.Net Core MVC コントローラーは、コンストラクターを介して依存関係を明示的に要求します。 1. コンストラクター インジェクション 2. メソッド インジェクション (アクション レベル) 3. プロパティ インジェクション (サポートされていません) 4. ビュー インジェクション
コンストラクターの挿入: - サービスはコンストラクター パラメーターとして追加され、ランタイムはサービス コンテナー (IServiceCollection--DiContainer) からサービスを解決します。サービスは通常、非具象クラス (インターフェイス) を使用して定義されます。
メソッドインジェクション: - [FromService] 属性を使用すると、コントローラーインジェクションを使用せずにサービスをアクションメソッドに直接挿入できます。
プロパティ インジェクション 現在 (Asp.net コア) 組み込み IOC コンテナーはプロパティ インジェクションをサポートしていません。このためには、サードパーティの組み込みサービス コンテナー (IOC) を使用することをお勧めします。
[Inject] ディレクティブを使用したビュー インジェクションにより、コントローラーやメソッド インジェクションを使用せずにビュー ページにサービスを直接挿入できます。
組み込み IoC コンテナは、次の 3 種類のライフタイムをサポートします。
サンプル例では、「IMyDependency」サービスインターフェースが「WriteMessage」メソッドを定義しています。
public interface IMyDependency
{
void WriteMessage(string message);
}
このインターフェイスは、具象型 MyDependency によって実装されます。
public class MyDependency : IMyDependency
{
public void WriteMessage(string message)
{
Console.WriteLine($"MyDependency.WriteMessage Message: {message}");
}
}
次に、「IMyDependency」サービスを具体的なタイプ「MyDependency」で登録します(startup.cs 内)
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.Add(new ServiceDescriptor(typeof(IMyDependency), new MyDependency()));
}
}
ここでは、「IServiceCollection」インスタンスの Add() メソッドを使用して、サービスを IoC コンテナに登録します。 「ServiceDescriptor」はサービスの種類と具体的な実装を指定するために使用されます。これにより、サービスがデフォルトの「Singleton」でコンテナに登録されます。
次に、異なる存続期間を持つサービスを注入してみましょう
シングルトン (ユースケース: 状態サービスを作成する必要がある場合):
services.Add(new ServiceDescriptor(typeof(IMyDependency), new MyDependency(),ServiceLifetime.Singleton));
一時的 (ユースケース: ステートレス サービスを作成する必要がある場合):
services.Add(new ServiceDescriptor(typeof(IMyDependency), new MyDependency(),ServiceLifetime.Transient));
スコープ付き (ユースケース: データベース サービス):
services.Add(new ServiceDescriptor(typeof(IMyDependency), new MyDependency(),ServiceLifetime.Scoped));
組み込みの拡張メソッドを使用してサービスを注入することもできます
シングルトン
services.AddSingleton
過渡現象
services.AddTransisent
スコープ付き
services.AddScoped
public class HomeController : Controller { private readonly IMyDependency _service;
public HomeController(IMyDependency service)
{
_service = service;
}
public IActionResult Index()
{
_service.WriteMessage("Constructor level injection")
return View();
}
}
public class HomeController : Controller
{
//Fromservice attribute
public IActionResult Index([FromService]IMyDependency service)
{
service.WriteMessage("Action level injection")
return View();
}
}
パブリック クラス HomeController : コントローラー {
public IActionResult Index()
{
return View();
}
}
Index.cshtml 内
@{ ViewData["タイトル"] = "ホームページ"; }
//using Inject directive
@inject IMyDependency service
//code block
@{
service.WriteMessage("View level Injection");
}
パブリック クラス HomeController : コントローラー {
public IActionResult Index()
{
var services = this.HttpContext.RequestServices;
var dependencyservice = (IMyDependency)services.GetService(typeof(IMyDependency));
dependencyservice.WriteMessage("without injection, accessing dependent services");
return View();
}
}