Nservicebus N服务总线删除IBU-利用IPipelineContext和IMessageSession

Nservicebus N服务总线删除IBU-利用IPipelineContext和IMessageSession,nservicebus,nservicebus6,Nservicebus,Nservicebus6,我正在将NServiceBus迁移到v6,在删除对IBus的引用的过程中遇到了障碍 我们为许多应用程序(网站、微服务等)建立了一个公共库,该库具有IEventPublisher的概念,它本质上是一个发送和发布接口。该图书馆不了解NSB。 然后,我们可以使用应用程序中的DI提供这个IEventPublisher的实现,这使得库的消息传递可以很容易地被另一种技术取代 因此,我们最终得到的是一个类似于 public class NsbEventPublisher : IEventPublisher {

我正在将NServiceBus迁移到v6,在删除对IBus的引用的过程中遇到了障碍

我们为许多应用程序(网站、微服务等)建立了一个公共库,该库具有IEventPublisher的概念,它本质上是一个发送和发布接口。该图书馆不了解NSB。 然后,我们可以使用应用程序中的DI提供这个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);
}