在应用程序启动数据库种子期间使用范围服务

在应用程序启动期间解决作用域服务可能很困难,因为没有请求,因此没有作用域服务。

通过 app.ApplicationServices.GetService<AppDbContext>() 在应用程序启动期间解决作用域服务可能会导致问题,因为它将在全局容器的范围内创建,有效地使其成为应用程序生命周期的单例,这可能会导致像 Cannot access a disposed object in ASP.NET Core when injecting DbContext 这样的异常。

以下模式通过首先创建新作用域然后从中解析作用域服务来解决问题,然后在完成工作后,处理作用域容器。

public Configure(IApplicationBuilder app)
{
    // serviceProvider is app.ApplicationServices from Configure(IApplicationBuilder app) method
    using (var serviceScope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope())
    {
        var db = serviceScope.ServiceProvider.GetService<AppDbContext>();

        if (await db.Database.EnsureCreatedAsync())
        {
            await SeedDatabase(db);
        }
    }
}

这是实体框架核心团队在应用程序启动期间播种数据的半官方方式,并反映在 MusicStore 示例应用程序中。