使用ASP.Net Core依赖注入

时间:2018-04-12 16:04:12

标签: asp.net-core dependency-injection dbcontext

我已在Startup类中使用services.AddDbContext()配置了我的DbContext,并且我的控制器中的构造函数注入效果非常好。

默认情况下,它是一个范围内的服务,但我在应用程序中有一个位置,我希望在单独的工作范围内更新实体的单个属性。所以我需要在控制器中创建一个新的DbContext,但我不确定如何。我希望它由DI创建,所以我不必手动调用构造函数并提供所需的所有选项。有没有办法做到这一点?也许有一种方法可以从DI获取数据库上下文选项?然后我可以轻松地构建DbContext。

2 个答案:

答案 0 :(得分:2)

将DbContext注入Controller的常规方法可以正常工作,只要您在HTTP请求期间进行了合理的工作即可。但是,如果您正在运行后台/并行操作,或者正在查询和修改很多记录(由于SaveChangesAsync()正在跟踪{很多对象)。如果是这样,则可以为每个操作创建一个有作用域的DbContext。这是一个示例ASP.NET Core Controller方法:

DbContext.ChangeTracker

此外,我建议在Startup.cs中从 /// <summary> /// An endpoint that processes a batch of records. /// </summary> /// <param name="provider">The service provider to create scoped DbContexts. /// This is injected by DI per the FromServices attribute.</param> /// <param name="records">The batch of records.</param> public async Task<IActionResult> PostRecords( [FromServices] IServiceProvider provider, Record[] records) { // The service scope factory is used to create a scope per iteration var serviceScopeFactory = provider.GetRequiredService<IServiceScopeFactory>(); foreach (var record in records) { // At the end of the using block, scope.Dispose() will be called, // releasing the DbContext so it can be disposed/reset. using (var scope = serviceScopeFactory.CreateScope()) { var context = scope.ServiceProvider.GetService<MainDbContext>(); // Query and modify database records as needed await context.SaveChangesAsync(); } } return Ok(); } 切换到AddDbContext(),以避免为每个请求创建/销毁DbContext对象。 DbContextPool超出范围后,会将DbContext对象重置为干净状态。 (如果您有兴趣,DbContextPool会调用AddDbContextPool()DbContext.ResetState(),但是我不建议直接从您的代码中调用它们,因为它们可能会在将来的版本中更改。) https://github.com/aspnet/EntityFrameworkCore/blob/v2.2.1/src/EFCore/Internal/DbContextPool.cs#L157

答案 1 :(得分:0)

一种选择是将IDbContextFactory注入您的comtroller以在using块内创建上下文。

https://msdn.microsoft.com/en-us/library/hh506876(v=vs.113).aspx