ASP.NET Core将DbContext依赖关系解析为init迁移

问题描述 投票:2回答:1

ASP.NET DI开箱即用并递归地解析所有构造函数依赖项,这很棒。虽然有时您希望能够直接访问DI容器。我想知道是否有办法?也许是这样的:

IService service = Container.Instance.Resolve<IService>();

我在docs中没有找到任何东西(虽然我知道,我可以替换内置的DI框架)。


在大多数情况下,您不需要它,但有一些特定情况。在我的情况下,我需要在应用启动时使用IoC容器初始化我的EF DbContext,以启动应该像EF Core那样工作的自动迁移:

using (var context = new MyContext())
{
    context.Database.Migrate();
}

我的上下文在容器中注册,但它位于一个单独的类库中。我不想直接称它为DbContextOptions构造函数。

c# dependency-injection asp.net-core .net-core di-containers
1个回答
3
投票

在问题得到更新并且很明显它正在进行EntityFramework Core迁移之后,ASP.NET核心团队就如何在应用程序启动期间正确解析DbContext有一种半官方的方式。

默认情况下,DbContext被注册为作用域服务,因此每个请求都会实例化一次。应用程序启动期间的问题是,目前还没有上下文,app.ApplicationServices方法中只有Configure可用,而ApplicationServices提供程序实际上是解析单例(范围是每个范围的单例,应用程序范围与应用程序一样长)。

所以诀窍是首先创建一个范围,解决DbContext,执行操作然后处理上下文(以及DbContext)。

可以在音乐商店示例应用程序qazxsw poi和qazxsw poi中找到示例。

截至目前,这是解决它的唯一安全方式,不会导致任何问题,即处置对象异常。

另请注意,您可以执行此操作的最早点是使用here方法,因为只有IoC容器才构建完成。在here你只填充Configure

相关代码片段:

ConfigureServices

编辑:

有关此问题的其他资源:

  • 关于GitHub的IServiceCollection问题,@ divega的初步提案。
  • void Configure(IApplicationBuilder app) { //Populates the MusicStore sample data SampleData.InitializeMusicStoreDatabaseAsync(app.ApplicationServices).Wait(); } public static class SampleData { ... public static async Task InitializeMusicStoreDatabaseAsync(IServiceProvider serviceProvider, bool createUsers = true) { using (var serviceScope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope()) { var db = serviceScope.ServiceProvider.GetService<MusicStoreContext>(); if (await db.Database.EnsureCreatedAsync()) { await InsertTestData(serviceProvider); if (createUsers) { await CreateAdminUser(serviceProvider); } } } } } (该问题的结束评论)
  • 关于GitHub的Pattern for seeding database with EF7 in ASP.NET 5问题
© www.soinside.com 2019 - 2024. All rights reserved.