Nservicebus N服务总线删除IBU-利用IPipelineContext和IMessageSession
我正在将NServiceBus迁移到v6,在删除对IBus的引用的过程中遇到了障碍 我们为许多应用程序(网站、微服务等)建立了一个公共库,该库具有IEventPublisher的概念,它本质上是一个发送和发布接口。该图书馆不了解NSB。 然后,我们可以使用应用程序中的DI提供这个IEventPublisher的实现,这使得库的消息传递可以很容易地被另一种技术取代 因此,我们最终得到的是一个类似于Nservicebus N服务总线删除IBU-利用IPipelineContext和IMessageSession,nservicebus,nservicebus6,Nservicebus,Nservicebus6,我正在将NServiceBus迁移到v6,在删除对IBus的引用的过程中遇到了障碍 我们为许多应用程序(网站、微服务等)建立了一个公共库,该库具有IEventPublisher的概念,它本质上是一个发送和发布接口。该图书馆不了解NSB。 然后,我们可以使用应用程序中的DI提供这个IEventPublisher的实现,这使得库的消息传递可以很容易地被另一种技术取代 因此,我们最终得到的是一个类似于 public class NsbEventPublisher : IEventPublisher {
public class NsbEventPublisher : IEventPublisher
{
IEndpointInstance _instance;
public NsbEventPublisher(IEndpointInstance endpoint)
{
instance = endpoint;
}
public void Send(object message)
{
instance.Send(message, sendOptions);
}
public void Publish(object message)
{
instance.Publish(message, sendOptions);
}
}
这是对实际情况的简化,但说明了我的问题。
现在,当DI容器被请求一个IEventPublisher时,它知道返回一个NsbEventPublisher,并且知道解析IEndpointInstance,因为我们在网站的引导程序中将它作为一个单例绑定到容器。
一切都很好,我的网站运行完美
我现在正在迁移微服务(在NSB.Host中运行),而DI容器在解析消息处理程序中的依赖项时拒绝解析IEndpointInstance。阅读文档这是有意的,我应该在消息处理程序中使用IMessageHandlerContext。
这些文档甚至回避了我在下面示例中遇到的关于类MyContextAccessingDependency的问题。建议通过方法传递消息上下文,该方法对消息处理程序上下文中运行的代码具有硬依赖性
我想做的是访问发送者/发布者,DI容器可以给我正确的实现。代码不需要调用方的任何概念,也不需要从消息处理程序或只想发布的自托管应用程序调用它
我看到有两个接口用于与“总线”IPipelineContext和IMessageSession通信,IMessageHandlerContext和IEndpointInstance接口分别扩展了这两个接口。
我想知道的是,NSB将这两个接口绑定到容器中,这样我就可以接受发送/发布消息的接口。在处理程序中,它是一个IMessageHandlerContext,在我的自托管应用程序中是IEndPointInstance
目前,我希望根据应用程序托管更改IEventPublisher的实现。我只是希望大家能讨论一下,在没有可靠的发送/发布接口的情况下,这种方法是如何建模的,而不管是什么启动了代码路径的执行。在开始编写代码之前,需要注意以下几点:
- 抽象而不是抽象的承诺,永远不会起作用。我从未见过“我将抽象ESB/Messaging/Database/ORM,以便在将来交换它”的说法。永远
- 当您抽象出这样的消息发送功能时,您将失去库提供的一些功能。在这种情况下,您不能执行“对话”或使用会妨碍您整体体验的“传奇”,例如,在ServiceInsight中使用监视工具和查看图表时,您将看不到整个画面,而只能看到通过系统传递的消息的数量
IEndpointInstance
。然后可以在依赖项注入中使用该接口,例如在NsbEventPublisher
中发送消息
类似这样的内容(取决于您使用的IoC容器,这里我假设Autofac):
静态异步任务AsyncMain()
{
IEndpointInstance端点=null;
var builder=new ContainerBuilder();
注册器(x=>endpoint)
.As()
.SingleInstance();
//端点配置在这里。。。
端点=等待端点.Start(总线配置)
.配置等待(错误);
}
其中提到了使用IEndpointInstance/IMessageSession的问题。感谢您抽出时间回答。我已经成功地将IEndpointInstance绑定到容器中,正如您在自托管环境中所描述的那样。类似地,当由NSB.Host托管时,IMessageHandlerContext在处理消息时由NSB绑定到容器中。同意您关于抽象而非抽象的想法,但对于我们来说,它在这个用例中工作得非常好。我对你最后一句关于使用IEndpointInstance/IMessageSession的话很感兴趣,我们如何从容器中请求一个简单的发送/发布接口,并允许NSB为我们绑定它。我很乐意提供帮助,但这似乎超出了上述问题的范围。请随时给我发送电子邮件,以支持特定网站,我会回复您:)
static async Task AsyncMain()
{
IEndpointInstance endpoint = null;
var builder = new ContainerBuilder();
builder.Register(x => endpoint)
.As<IEndpointInstance>()
.SingleInstance();
//Endpoint configuration goes here...
endpoint = await Endpoint.Start(busConfiguration)
.ConfigureAwait(false);
}