![](/img/trans.png)
[英]ASP.NET Core - Dependency Injection - IdentityServer4 DbContext
[英]ASP.NET Core resolve DbContext dependency to init migrations
ASP.NET DI开箱即用,并递归解析所有构造函数依赖关系,这是非常好的。 尽管有时您希望能够直接访问DI容器。 我想知道是否有办法? 也许是这样的:
IService service = Container.Instance.Resolve<IService>();
我没有在文档中找到任何内容(尽管我知道,我可以替换内置的DI框架)。
在大多数情况下,您不需要它,但是有一些特定的情况。 在我的情况下,我需要在应用程序启动时使用IoC容器初始化EF DbContext,以启动应该与EF Core一样工作的自动迁移:
using (var context = new MyContext())
{
context.Database.Migrate();
}
我的上下文在容器中注册,但是在单独的类库中。 而且我不想直接将其DbContextOptions
构造函数。
在问题得到更新并且很明显要进行EntityFramework Core迁移之后,ASP.NET Core团队采用了一种半官方的方式来确定如何在应用程序启动期间正确解析DbContext
。
默认情况下, DbContext
被注册为范围服务,因此每个请求实例化一次。 应用程序启动期间的问题是,尚无上下文,只有app.ApplicationServices
可在Configure
方法中使用, ApplicationServices
提供程序本质上是解决单例(作用域是每个作用域的单例,并且只要应用程序运行,应用程序范围就存在) 。
因此,诀窍是先创建一个作用域,解析DbContext
,执行操作,然后处置上下文(以及包含它的DbContext
)。
可以在此处和此处的MusicStore示例应用程序中找到示例。
到目前为止,这是解决该问题的唯一安全方法,不会引起任何问题,例如,处置对象异常。
还请注意,最早可以在Configure
方法中执行此Configure
,因为只有那时才构建了IoC容器。 在ConfigureServices
,仅填充IServiceCollection
。
相关代码段:
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);
}
}
}
}
}
编辑:
有关此问题的其他资源:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.