来自 NServiceBus Behavior 的范围依赖使用

Alp*_*a75 3 .net dependency-injection nservicebus asp.net-core

我正在尝试使用Scoped来自 NServiceBus的依赖项Behavior

来自NServiceBus 行为文档:

行为仅创建一次,并且在每次调用管道时都会重用相同的实例。因此,即使在依赖注入中注册时指定了不同的选项,每个行为依赖也将表现为单例。此外,在调用阶段调用的行为和所有依赖项需要是并发安全的并且可能是无状态的。应该避免在行为实例中存储状态,因为它会导致在所有消息处理会话中共享状态。这可能会导致不必要的副作用。

由于 aBehavior是单例并且 the 的Invoke方法Behavior不允许注入任何依赖项(例如invokenet core 中间件的方法,因为在这种情况下它是常规接口实现),因此我不能scoped从这里使用依赖项。

我试图Invoke通过在构造函数中传递 IServiceCollection来解决我的方法中每个传入/传出消息的依赖项:

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 
}
Run Code Online (Sandbox Code Playgroud)

但这不起作用

那是因为当您将 IServiceProvider 注入中间件时 - 那是“全局”提供者,而不是请求范围的。调用中间件构造函数时没有请求(中间件在启动时创建一次),因此它不能是请求范围的容器。

总之,我的作用域依赖包含当前上下文的数据,我想从Invoke我的Behavior单例方法访问这些数据?

有什么办法吗?

Ale*_*bov 5

在解决依赖关系之前,您需要创建一个范围:

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>();
    }
}
Run Code Online (Sandbox Code Playgroud)

另外,请注意您的依赖项与范围一起处理。

  • @Alpha75 恐怕行为超出了您的请求范围,因此无法使用为 HttpContext 创建的值解析范围依赖项。 (2认同)