NServiceBus Behavior中的范围依赖项使用 [英] Scoped dependency use from NServiceBus Behavior

查看:95
本文介绍了NServiceBus Behavior中的范围依赖项使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用NServiceBus Behavior中的Scoped依赖项.

I'm trying to use a Scoped dependency from a NServiceBus Behavior.

来自 NServiceBus行为文档:

行为仅创建一次,并且相同的实例在以下位置重用 管道的每次调用.因此,每一种行为 依赖项也将表现为单例行为,即使使用其他选项也是如此 在依赖注入中注册时指定. 此外,行为以及在运行期间调用的所有依赖项 调用阶段,需要并发安全并且可能是无状态的. 应避免将状态存储在行为实例中,因为这样做会 使状态在所有消息处理会话之间共享. 这可能会导致不良的副作用.

Behaviors are only created once and the same instance is reused on every invocation of the pipeline. Consequently, every behavior dependency will also behave as a singleton, even if a different option was specified when registering it in dependency injection. Furthermore, the behavior, and all dependencies called during the invocation phase, need to be concurrency safe and possibly stateless. Storing state in a behavior instance should be avoided since it will cause the state to be shared across all message handling sessions. This could lead to unwanted side effects.

由于Behavior是Singleton,并且BehaviorInvoke方法不允许注入任何依赖项(例如,网络核心中间件的invoke方法,因为在这种情况下,这是常规的接口实现),我不能在这里使用scoped依赖项.

Since a Behavior is a Singleton and the Invoke method of the Behavior doesn't allow to inject any dependency (such as the invoke method of a net core middleware because in this case it's a regular interface implementation), I can't use a scoped dependency from here.

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

I've tried to resolve my dependencies in my Invoke method for each incoming/outgoing message by passing IServiceCollection in the constructor:

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 
}

但这不是工作:

那是因为当您将IServiceProvider注入中间件时- 那是全局"提供者,不是请求范围的.何时没有要求 您的中间件构造函数被调用(中间件在以下位置创建一次) 启动),因此它不能是请求范围的容器.

That's because when you inject IServiceProvider into your middleware - that's "global" provider, not request-scoped. There is no request when your middleware constructor is invoked (middleware is created once at startup), so it cannot be request-scoped container.

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

In summary, my scoped dependency contains data for the current context and I'd like to access this data from the Invoke method of my Behavior singleton?

有什么办法吗?

推荐答案

您需要先创建作用域,然后再解决依赖项:

You need to create a scope before resolving your dependency:

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>();
    }
}

此外,请注意,您的依赖项会与范围一起处置.

Also, pay attention that your dependency is disposed along with scope.

这篇关于NServiceBus Behavior中的范围依赖项使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆