问题描述
我对使用依赖注入不熟悉,在我的blazor项目中走了很长一段路才真正开始使用它。
我添加了DBContext作为瞬态服务(如此处的许多答案所述),并将其注入到DataAccessLayer中,如下所示:
public class DataAccessLayer
{
public DataAccessLayer(GlobalVariables s,DataContext d)
{
GlobalVariables = s;
context = d;
}
private readonly GlobalVariables GlobalVariables;
private readonly DataContext context;
`/other code here`
现在,当我打开一页时,在blazor项目中使用剃刀组件时,大约有5个组件开始渲染。所有这些组件都从DataAccessLayer提取数据。
我遇到了这两个错误:
System.InvalidOperationException: Invalid attempt to call ReadAsync when reader is closed.
System.InvalidOperationException: A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext. For more information on how to avoid threading issues with DbContext
当我删除依赖项并添加(使用Datacontext)时,错误消失并且运行良好。有人可以建议我如何正确注射吗?
PS:我已经检查过我所有的异步方法都具有await和configureawait(true)
引发readasync的第一个异常的方法是:
public async Task<List<MasterCustomer>> getCustomersBinding()
{
List<MasterCustomer> customersList = new List<MasterCustomer>();
{
customersList = await (from table in context.MasterCustomer where (table.IsActive == true) select (new MasterCustomer { Code = table.Code,Name = table.Name })).ToListAsync().ConfigureAwait(true); ;
}
return customersList;
}
解决方法
configureawait(true)在ASP.NET Core中没有用。
为避免Entity Framework Core和注入的上下文出现线程问题,请注入IServiceScopeFactory并使用以下模式
using (var scope = _scopeFactory.CreateScope())
{
var dbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
do whatever you want with dbContext
}
,
您的DataAccess层也需要是瞬态的,否则您将获得一个带范围的实例,该实例始终保留创建的DbContext的第一个瞬态实例。
最后,请确保您从OwningComponentBase<T>
降级组件,否则不会处理您注入的依赖项。
@inherits OwningComponentBase<DataAccessLayer>
然后,您可以通过DataAccessLayer
访问this.Service
,并且在处置组件时也将处置this.Service
。