主旨
ASP.Net Core デフォルトのDIシステムを使用して、依存関係の解決方法を記載する。
特に、コンストラクタの引数も自動で解決してくれる点は、フレームワークにより実装が隠ぺいされているため、理解が必要である。
前提
今回は、以下の依存関係を持つアーキテクチャで説明を行う。
より細かなイメージを掴みたい場合、こちらの記事を参照。
また、Entity FrameworkのDI設定に関しては、公式ドキュメントを参照。
- Repositoryの実装は、Entity Frameworkに移譲する。
- ApplicationServiceからのデータアクセスは、Repositoryに移譲する。
- ApplicationServiceはRepositoryInterfeceに依存する。
- Controllerの具体的な処理はApplicationServiceに移譲する。
依存関係を明示的に解決する場合
public class Repository : IRepository
{
private readonly DbContext _dbContext;
public Repository(DbContext dbContext) => _dbContext = dbContext;
}
public class ApplicationService
{
private readonly IRepository _repository;
public ApplicationService(IRepository repository) => _repository = repository;
public ViewModel Do() => new ViewModel();
}
public class HomeController : Controller
{
// DbContextは、DIシステムより取得する。
private readonly DbContext _dbContext;
public HomeController(DbContext dbContext) => _dbContext = dbContext;
public IActionResult Index()
{
// ドメイン側の依存関係を手動で解決する場合。
// ApplicationServiceをインスタンス化するためには、2つの依存関係の注入を行う。
// RepositoryにはDbContextを注入する。
// ApplicationServiceには、Repositoryを注入する。
var repository = new Repository(_dbContext);
var service = new ApplicationService(repository);
var viewModel = service.Do();
return View(viewModel);
}
}
全ての依存関係をDIシステムで解決する場合
// Stratup.cs
public void ConfigureServices(IServiceCollection services)
{
// DbContextのDI設定
services.AddDbContext<DbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
// ドメイン側のDI設定
// DIシステムに追加するだけで、各クラスの依存関係を解決してくれる。
services.AddTransient<IRepository, Repository>();
services.AddTransient<ApplicationService>();
}
public class HomeController : Controller
{
private readonly IServiceProvider _provider;
public HomeController(IServiceProvider provider) => _provider = provider;
public IActionResult Index()
{
// これだけで呼び出せる。
var service = _provider.GetService<ApplicationService>();
var viewModel = service.Do();
return View(viewModel);
}
}
まとめ
ASP.net Core デフォルトのDIシステムを活用して、依存関係を簡潔に自動解決できるようになった。
フレームワークを知ることで、適切な方法で実装できるようになった。
ただし、フレームワークを使用することは、実装部分がブラックボックスになるというトレードオフになる点を知った。