Blazor 中的依赖注入与 Razor 组件

Posted

技术标签:

【中文标题】Blazor 中的依赖注入与 Razor 组件【英文标题】:Dependency injection in Blazor with Razor components 【发布时间】:2020-12-10 20:03:11 【问题描述】:

我是使用依赖注入的新手,在我真正开始使用它之前,我已经在我的 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 项目中使用 razor 组件,大约 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;
    

【问题讨论】:

你在哪里打电话给ReadAsync?你能显示那个方法的代码吗 编辑问题以在其末尾添加询问的代码。 My answer 带有官方指南的链接,以将 EF 与 Blazor 服务器端结合使用。 【参考方案1】:

您的 DataAccess 层也需要是瞬态的,否则您将获得一个范围内的实例,该实例始终保留创建的 DbContext 的第一个瞬态实例。

最后,确保你的组件从 OwningComponentBase&lt;T&gt; 下降,否则你注入的依赖将不会被释放。

@inherits OwningComponentBase<DataAccessLayer>

然后你可以通过this.Service访问DataAccessLayerthis.Service会在你的组件被释放的时候被释放。

https://blazor-university.com/dependency-injection/

【讨论】:

【参考方案2】:

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
            

【讨论】:

是否比不使用 DBContext 作为依赖项并简单地添加 using(var context= new DataContext(GlobalVariables)) 更好?因为如果我也这样做,应用程序运行良好。 以上是建议的模式。在这种情况下,直接使用 dbcontext 也是一样的。

以上是关于Blazor 中的依赖注入与 Razor 组件的主要内容,如果未能解决你的问题,请参考以下文章

将组件的依赖注入方法移动到 Blazor 服务器端中的分离 CS 库

Blazor 的依赖注入问题

Blazor University (52)依赖注入 —— 拥有多个依赖项:正确的方式

带有私有 NuGet 包的 Blazor 依赖项注入和 EF/DbContext

Blazor University (48)依赖注入 —— Scoped 依赖

如何从 Blazor 服务器端应用程序中的 Razor 页面导航到 Blazor 组件?