如何使用.NET Core解析类库中的DI类?

Rog*_*ger 4 dependency-injection .net-core asp.net-core asp.net-core-2.0

我了解 .NET Core 中 DI 的基础知识,但我无法弄清楚如何在多个项目中使用它。想象一下我正在 ASP.NET Core 的 Startup 类中设置数据库上下文:

public void ConfigureServices(IServiceCollection services)
{
  services.AddDbContext<GalleryDb>();
}
Run Code Online (Sandbox Code Playgroud)

我知道如何在 API 控制器中访问该上下文:

public class AlbumController : Microsoft.AspNetCore.Mvc.Controller
{
  private GalleryDb _ctx;

  public AlbumController(GalleryDb ctx)
  {
    _ctx = ctx;
  }
}
Run Code Online (Sandbox Code Playgroud)

但是,当 API 控制器和数据访问类之间有很多层和函数时该怎么办呢?最终代码到达我的存储库类,这是实际需要上下文的类。它看起来像这样:

public class AlbumRepository
{
  private GalleryDb _ctx;
  public AlbumRepository(GalleryDb ctx)
  {
    _ctx = ctx;
  }

  public void Save(AlbumEntity entity)
  {
    // Use _ctx to persist to DB.
  }
}
Run Code Online (Sandbox Code Playgroud)

我知道我可以从 API 入口点一直向下传递上下文,但这似乎是一种反模式,因为这意味着将它作为参数传递给多个对此不感兴趣的类和函数。

相反,我想在调用存储库类时执行类似的操作:

public void Save(AlbumEntity album)
{
  var ctx = DependencyResolver.GetInstance<GalleryDb>();
  var repo = new AlbumRepository(ctx);
  repo.Save(album);
}
Run Code Online (Sandbox Code Playgroud)

我相信一些 DI 框架有类似的东西,但我正在尝试弄清楚如何使用本机 .NET Core 2.0 来做到这一点。这可能吗?最佳实践是什么?我发现一个线程(ASP.NET Core DependencyResolver)谈论使用 IServiceProvider,但暗示这不是一个理想的解决方案。

我希望无论解决方案是什么,我都可以将其扩展到其他 DI 类,例如 ASP.NET Identity 的 RoleManager 和 SignInManager。

Rog*_*ger 5

chris-pratt 帮助我理解的关键突破是,唯一可行的方法是在所有层中使用 DI 。例如,在数据层中,我通过 DI 获取数据库上下文:

public class AlbumRepository
{
  private GalleryDb _ctx;
  public AlbumRepository(GalleryDb ctx)
  {
    _ctx = ctx;
  }
}
Run Code Online (Sandbox Code Playgroud)

在业务层我使用DI来获取对数据层的引用:

public class Album
{
  private AlbumRepository _repo;
  public Album(AlbumRepository repo)
  {
    _repo = repo;
  }
}
Run Code Online (Sandbox Code Playgroud)

然后,在Web层中,我使用DI来获取对业务层类的引用:

[Route("api/[controller]")]
public class AlbumController : Microsoft.AspNetCore.Mvc.Controller
{
  private Album _album;
  public AlbumController (Album album)
  {
    _album = album;
  }
}
Run Code Online (Sandbox Code Playgroud)

通过在每一层使用 DI,DI 系统能够在需要的地方构造所有必要的类。

这一要求对应用程序的架构产生了深远的影响,我现在意识到,我最初希望调整现有的非 DI 应用程序以开始在数据库上下文中使用 DI 是一项重大任务。