Blazor服务器应用程序和IDbContentFactory未处理



我有一个blazor服务器应用程序,它需要间接连接到EF核心DB上下文。

没有一个blazor组件会直接注入dbcontext的实例。我正在使用中介,它将处理所有业务操作。

到目前为止,我看到的文档建议使用IDbContentFactory。我尝试了一下,但我没有看到工厂创建的DbContext被处理。注入IDbContext的服务不会在页面更改时释放,也不会在任何其他时间释放。

public class QueryHandler : IQueryHandler<Query, Entity>, IDisposable
{
private readonly DbContext dbContext;
public QueryHandler(IDbContextFactory factory)
{
dbContext = factory.CreateDbContext();
}
public Task Handle(Query query)
{
/// do whatever needs to be done.
}

public void Dispose()
{
dbContext.Dispose(); // <-- Dispose never gets called.
}
}

我是不是错过了什么?

使用DbContextFactory的目的是每个方法都有一个DbContext。正是因为Blazor没有提供有用的Scopes来处理这一问题。

public class QueryHandler : IQueryHandler<Query, Entity> //, IDisposable
{
...
public QueryHandler(IDbContextFactory factory)
{
_factory = factory;
}
public Task Handle(Query query)
{
using var dbContext = _factory.CreateDbContext();
/// do whatever needs to be done.
}

//public void Dispose() { }
}

通过这种方式,DI容器和工厂只管理DbContext的配置。DbContext的生命周期管理是手动的。工厂是一个简单的瞬态对象,不拥有任何资源。

手动管理通常使用using语句或using声明,但Blazor也提供OwningComponentBase。我看它用得不多。

在服务器中,DI容器在集线器会话的生存期内存在,在WASM中存在应用程序的生存期。在容器中创建的任何服务对象,无论是Scoped还是Transient,实现IDisposable,都不会被丢弃,直到DI容器本身被销毁。您没有弄清楚QueryHandler的范围,但如果它是瞬态的,那就是坏消息。您将继续创建新的DBContexts,而不会丢弃旧的DBContext。

DbContextFactory的目的是创建使用的工作单元DbContext实例,然后快速正确地进行处理。您需要采取这种方法,因为数据库访问几乎肯定是异步的。使用单个上下文,您将很快遇到这样的情况:您正在等待一个查询完成,同时试图在另一个操作中使用相同的上下文。

Henk的回答向您展示了如何使用和消费工厂创建的上下文。

相关内容

  • 没有找到相关文章

最新更新