我正在尝试使用NServiceBus Scoped
中的Behavior
依赖项。
来自NServiceBus Behavior文档:
行为仅创建一次,并且相同实例被重用 管道的每次调用。因此,每一种行为 依赖项也将表现为单例,即使使用其他选项 在依赖注入中注册时指定。 此外,行为以及在 调用阶段,需要并发安全并且可能是无状态的。 应避免将状态存储在行为实例中,因为这样会 使状态在所有消息处理会话之间共享。 这可能会导致不良的副作用。
由于Behavior
是单例,并且Invoke
的{{1}}方法不允许注入任何依赖项(例如网核的Behavior
方法中间件,因为在这种情况下,它是常规的接口实现),因此我不能从此处使用invoke
依赖项。
我试图通过在构造函数中传递IServiceCollection来解决我的scoped
方法中对每个传入/传出消息的依赖关系:
Invoke
那是因为当您将IServiceProvider注入中间件时- 那是“全局”提供者,不是请求范围的。何时没有要求 您的中间件构造函数被调用(中间件创建一次) 启动),因此它不能是请求范围的容器。
总而言之,我的作用域依赖项包含当前上下文的数据,我想从我的private readonly IServiceCollection _services;
public MyIncomingMessageBehavior(IServiceCollection services)
{
_services = services;
}
public override async Task Invoke(IIncomingLogicalMessageContext context, Func<Task> next)
{
var myScopedDependency = _services.BuildServiceProvider().GetService<IMyScopedDependency>();
// always
}
单例的Invoke
方法访问此数据吗?
有什么办法吗?
答案 0 :(得分:3)
您需要先创建一个范围,然后再解决依赖关系:
private readonly IServiceScopeFactory _scopeFactory;
public MyIncomingMessageBehavior(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public override async Task Invoke(IIncomingLogicalMessageContext context, Func<Task> next)
{
using(var scope = _scopeFactory.CreateScope())
{
var myScopedDependency = scope.ServiceProvider.GetService<IMyScopedDependency>();
}
}
此外,请注意,您的依赖项与作用域一起被处置。