masstransit - 让 Masstransit 使用范围生命周期
问题描述
我在消费者观察者中获取 IIdentityService(我自己的类)或 IServiceProvider 的相同实例时遇到问题。我有一个身份服务,我在其中为用户设置凭据,稍后在消费者管道中使用。
我已经尝试了下面的代码以及其他代码和配置更改。
_serviceProvider.GetRequiredService<IIdentityService>()
_serviceProvider.CreateScope()
var consumerScopeProvider = _serviceProvider.GetRequiredService<IConsumerScopeProvider>();
using (var scope = consumerScopeProvider.GetScope(context))
{
// this next line of code is where we must access the payload
// using a container specific interface to get access to the
// scoped IServiceProvider
var serviceScope = scope.Context.GetPayload<IServiceScope>();
var serviceProviderScoped = serviceScope.ServiceProvider;
IIdentityService identityService = _serviceProvider.GetRequiredService<IIdentityService>();
}
// Also tried this as Scoped
services.AddTransient<CustomConsumer>();
var busControl = Bus.Factory.CreateUsingRabbitMq(cfg =>
{
var host = cfg.Host(new Uri(busConfiguration.Address), h =>
{
h.Username(busConfiguration.Username);
h.Password(busConfiguration.Password);
});
cfg.ReceiveEndpoint(host, "queue_1", endpointCfg => ConfigureConsumers(endpointCfg, provider));
cfg.UseServiceScope(provider);
});
busControl.ConnectConsumeObserver(new ConsumeObserver(provider));
public class ConsumeObserver : IConsumeObserver
{
private readonly IServiceProvider _serviceProvider;
public ConsumeObserver(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
Task IConsumeObserver.PreConsume<T>(ConsumeContext<T> context)
{
var identityMessage = (IIdentityMessage)context.Message;
if (identityMessage == null)
{
return Task.CompletedTask;
}
// Here I get a "Cannot resolve scoped service '' from root provider." error
IIdentityService identityService = _serviceProvider.GetRequiredService<IIdentityService>();
var task = identityService.SetIdentityAsync(identityMessage.Identity.TenantIdentifier, identityMessage.Identity.UserIdentifier);
// This gets a different instance of the IIdentityService.cs service.
//IIdentityService identityService = _serviceProvider.CreateScope().ServiceProvider.GetRequiredService<IIdentityService>();
// called before the consumer's Consume method is called
return task;
}
Task IConsumeObserver.PostConsume<T>(ConsumeContext<T> context)
{
// called after the consumer's Consume method is called
// if an exception was thrown, the ConsumeFault method is called instead
return TaskUtil.Completed;
}
Task IConsumeObserver.ConsumeFault<T>(ConsumeContext<T> context, Exception exception)
{
// called if the consumer's Consume method throws an exception
return TaskUtil.Completed;
}
}
// This is where I need to identity credentials
services.AddScoped<UserContext>((provider =>
{
// This gets a different instance of IIdentityService
var identityService = provider.GetRequiredService<IIdentityService>();
var contextProvider = provider.GetRequiredService<IContextProvider>();
var identity = identityService.GetIdentity();
return contextProvider.GetContext(identity.UserId);
}));
var task = identityService.SetIdentityAsync(identityMessage.Identity.TenantIdentifier, identityMessage.Identity.UserIdentifier);
上面的身份设置应该可以在下面检索。
var identity = identityService.GetIdentity();
我得到的是空引用,因为服务提供者是不同的实例。
谁能告诉我如何通过消费者管道获取服务提供者的相同实例?
解决方案
推荐阅读
- visual-studio-code - VSCODE。如何通过单击打开包含变量或 html 标记的文件?
- ios - 在 performDropWith 委托回调中访问源表视图
- c# - 更新(更新回退)具有子实体的实体列表的正确方法?
- php - 使用php将数据infile加载到oracle表中
- python - 通过使用 Python 计算行范围内的元素来创建新列
- python - 在循环中将一个列表的每个元素与第二个列表的四个元素相乘以获得新列表的函数
- drools - Drools 7.x 中“KnowledgeAgentConfiguration”属性的替代品是什么?
- python - 在 django 中从 rest API 运行 Python 脚本
- docker - 基于 Docker 的 graylog 权限
- laravel - 如何延迟每个被推入单个队列的作业