我是使用依赖注入的新手,在真正开始使用它之前,我在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(时,错误就会消失,并且运行良好。有人能建议我如何正确注射吗?
p.S:我已经检查了我所有的异步方法是否都有等待和配置等待(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;
}
您的DataAccess层也需要是瞬态的,否则您将获得一个始终保持创建的DbContext的第一个瞬态实例的作用域实例。
最后,请确保您的组件是从OwningComponentBase<T>
派生的,否则您注入的依赖项将不会被处理。
@inherits OwningComponentBase<DataAccessLayer>
然后您可以通过this.Service
访问DataAccessLayer
,当您的组件被释放时,this.Service
将被释放。
https://blazor-university.com/dependency-injection/
configurewait(true(在ASP.NET Core中是无用的。
为了避免实体框架核心和注入的上下文出现线程问题,请注入IServiceScopeFactory,并使用以下模式
using (var scope = _scopeFactory.CreateScope())
{
var dbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
do whatever you want with dbContext
}