gpt4 book ai didi

c# - 在 RabbitMQ Consumer(单例服务)中使用 DbContext

转载 作者:太空狗 更新时间:2023-10-29 21:16:12 27 4
gpt4 key购买 nike

我有一个工作正常的 RabbitMQ 单例,但每当消息到达时都依赖于作用域服务:

consumer.Received += _resourcesHandler.ProcessResourceObject; //Scoped Service

我的服务是这样注册的:

services.AddScoped<IHandler, Handler>();
services.AddSingleton<RabbitMqListener>();

作用域服务构造函数使用 DI 作为 Db 上下文:

private readonly ApplicationDbContext _appDbContext;

public ResourcesHandler(ApplicationDbContext appDbContext)
{
_appDbContext = appDbContext;
}

此作用域服务调用 Db 上下文,以便在收到消息时将属性插入数据库。

但是,由于作用域服务的生命周期不同,因此启动失败。

有更好的方法吗?我可以将作用域服务设为单例,但随后我会遇到使用 DbContext 作为依赖项的问题。

DI 中用于在单例服务中调用 dbContext 的“协议(protocol)”是什么?

我可以使用 using 语句来确保它已被处置,但是我必须改为使用 DI 来传递 DbContextOptions。这是实现这一目标的唯一方法吗?

最佳答案

一种方法是自己创建作用域。通常 asp.net core 在请求开始时为您创建范围,并在请求结束时关闭范围。但在你的情况下 - rabbitmq 消息消费与 http 请求根本无关。不过,您可以说,每个消息处理都代表其自己的范围。

在这种情况下,注入(inject) IServiceProviderRabbitMqListener (在下面表示为 _provider 私有(private)字段)然后:

private void OnMessageReceived(Message message) {
using (var scope = _provider.CreateScope()) {
var handler = scope.ServiceProvider.GetRequiredService<IHandler>();
handler.ProcessResourceObject(message);
}
}

另一种方法是注册 ApplicationDbContext容器中的工厂(除了常规范围内的注册)。工厂将返回 ApplicationDbContext 的新实例这将是调用者的责任来处理它。例如:

services.AddSingleton<Func<ApplicationDbContext>>(() =>
{
var optionsBuilder = new DbContextOptionsBuilder<ApplicationDbContext>();
optionsBuilder.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
return new ApplicationDbContext(optionsBuilder.Options);
});

然后就可以注册了IHandler作为单例(并且不像现在那样限定范围)并注入(inject) Func<ApplicationDbContext>在其构造函数中:

private readonly Func<ApplicationDbContext> _appDbContextFactory;

public ResourcesHandler(Func<ApplicationDbContext> appDbContextFactory)
{
_appDbContextFactory = appDbContextFactory;
}

然后,每当您需要在处理程序中处理消息时——您自己管理上下文:

using (var context = _appDbContextFactory()) {
// do stuff
}

关于c# - 在 RabbitMQ Consumer(单例服务)中使用 DbContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49728884/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com