NServicebus 与 WebAPI 依赖范围共享嵌套容器
NServicebus share nested container with WebAPI dependency scope
是否可以share/use WebAPI 依赖解析器创建的嵌套容器?
structuremap.web(我使用的是 structuremap 和 NServiceBus.StructureMap 和 UseContainer<StructureMapBuilder>(x => x.ExistingContainer(container))
)包提供了 IDependencyResolver
、IDependencyScope
实现,这些实现非常自我解释 -解析器是用根容器创建的,当请求范围时,它 returns 一个新的范围,它是用根的嵌套容器创建的。
我想知道的是,在 WebAPI 端点的上下文中,我能否与 NSB 共享该嵌套容器。 Looking here,结构图构建器的功能与 WebAPI 解析器的功能几乎相同 - container.GetNestedContainer()。这意味着我为每个使用总线的 (HTTP) 请求获得两个嵌套容器。
我的用例是我想创建一种 headers 桶,我可以将 headers 从 DelegatingHandler
放入,然后将它们从 [= =14=].
此问题也已发布在 google 组 here 上。我快速总结了阅读此问题的人的讨论:
- NServiceBus 仅在接收消息时创建嵌套容器。通过使用
IBus.Send
或 ASP.NET 管道中的类似方法,NServiceBus 使用它最初配置的容器(例如,用于解析消息突变器)。
- OWIN HTTP pass through 将传入请求的消息直接放在 queue 上。这也支持自定义扩展(例如添加 headers)。
- 您可以使用 DI 技巧解决来自不同(嵌套)容器的依赖关系,例如通过使用委托,但涉及一些复杂性。虽然线程静态可用于 DI 欺骗,但请注意,这将随着引入异步 API 的
NServiceBus
版本 6 被打破。
IBus
可以包装在一个助手中,该助手可以使用管道当前容器解析并附加 headers.
@Sabacc 总结了 NServiceBus google 组中讨论的可用选项。我们认为 IBus
包装器方法最适合我们的需求。下面是一个示例实现供参考
首先是一个用于添加到 header 存储桶的委托处理程序,此示例添加了授权令牌。如果设置了 header,则会从可通过 HttpRequestMessage.GetDependencyScope()
访问的当前依赖范围解析 HeaderBucket
实例。
public class AuthorizationTokenCapturingHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
AuthenticationHeaderValue header = request.Headers.Authorization;
if (header != null)
{
HeaderBucket bucket = (HeaderBucket)request.GetDependencyScope().GetService(typeof(HeaderBucket));
bucket.Add(new HeaderBucket.Header(HeaderConstants.AUTHORIZATION_TOKEN, header.Parameter));
}
return base.SendAsync(request, cancellationToken);
}
}
HeaderBucket
在容器配置中配置为瞬态,因此将仅在嵌套容器的生命周期内共享。
IBus
包装器很简单 - 只需包装对 Send 的总线拦截调用,并在发送的消息上设置已添加到存储桶中的 headers。
public class HeaderAwareBus : IHeaderAwareBus
{
private IBus _bus;
private HeaderBucket _bucket;
public HeaderAwareBus(IBus bus, HeaderBucket bucket)
{
_bus = bus;
_bucket = bucket;
}
public ICallback Send(object message)
{
foreach (HeaderBucket.Header header in _bucket)
{
_bus.SetMessageHeader(message, header.Key, header.Value);
}
return _bus.Send(message);
}
}
现在只需将您的控制器依赖项声明为 IHeaderAwareBus
,ASP.Net 管道将解决该问题,因此 HeaderBucket
来自从 [=19= 访问的同一嵌套容器]
是否可以share/use WebAPI 依赖解析器创建的嵌套容器?
structuremap.web(我使用的是 structuremap 和 NServiceBus.StructureMap 和 UseContainer<StructureMapBuilder>(x => x.ExistingContainer(container))
)包提供了 IDependencyResolver
、IDependencyScope
实现,这些实现非常自我解释 -解析器是用根容器创建的,当请求范围时,它 returns 一个新的范围,它是用根的嵌套容器创建的。
我想知道的是,在 WebAPI 端点的上下文中,我能否与 NSB 共享该嵌套容器。 Looking here,结构图构建器的功能与 WebAPI 解析器的功能几乎相同 - container.GetNestedContainer()。这意味着我为每个使用总线的 (HTTP) 请求获得两个嵌套容器。
我的用例是我想创建一种 headers 桶,我可以将 headers 从 DelegatingHandler
放入,然后将它们从 [= =14=].
此问题也已发布在 google 组 here 上。我快速总结了阅读此问题的人的讨论:
- NServiceBus 仅在接收消息时创建嵌套容器。通过使用
IBus.Send
或 ASP.NET 管道中的类似方法,NServiceBus 使用它最初配置的容器(例如,用于解析消息突变器)。 - OWIN HTTP pass through 将传入请求的消息直接放在 queue 上。这也支持自定义扩展(例如添加 headers)。
- 您可以使用 DI 技巧解决来自不同(嵌套)容器的依赖关系,例如通过使用委托,但涉及一些复杂性。虽然线程静态可用于 DI 欺骗,但请注意,这将随着引入异步 API 的
NServiceBus
版本 6 被打破。 IBus
可以包装在一个助手中,该助手可以使用管道当前容器解析并附加 headers.
@Sabacc 总结了 NServiceBus google 组中讨论的可用选项。我们认为 IBus
包装器方法最适合我们的需求。下面是一个示例实现供参考
首先是一个用于添加到 header 存储桶的委托处理程序,此示例添加了授权令牌。如果设置了 header,则会从可通过 HttpRequestMessage.GetDependencyScope()
访问的当前依赖范围解析 HeaderBucket
实例。
public class AuthorizationTokenCapturingHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
AuthenticationHeaderValue header = request.Headers.Authorization;
if (header != null)
{
HeaderBucket bucket = (HeaderBucket)request.GetDependencyScope().GetService(typeof(HeaderBucket));
bucket.Add(new HeaderBucket.Header(HeaderConstants.AUTHORIZATION_TOKEN, header.Parameter));
}
return base.SendAsync(request, cancellationToken);
}
}
HeaderBucket
在容器配置中配置为瞬态,因此将仅在嵌套容器的生命周期内共享。
IBus
包装器很简单 - 只需包装对 Send 的总线拦截调用,并在发送的消息上设置已添加到存储桶中的 headers。
public class HeaderAwareBus : IHeaderAwareBus
{
private IBus _bus;
private HeaderBucket _bucket;
public HeaderAwareBus(IBus bus, HeaderBucket bucket)
{
_bus = bus;
_bucket = bucket;
}
public ICallback Send(object message)
{
foreach (HeaderBucket.Header header in _bucket)
{
_bus.SetMessageHeader(message, header.Key, header.Value);
}
return _bus.Send(message);
}
}
现在只需将您的控制器依赖项声明为 IHeaderAwareBus
,ASP.Net 管道将解决该问题,因此 HeaderBucket
来自从 [=19= 访问的同一嵌套容器]