NServiceBus正在删除IBus - 利用IPipelineContext和IMessageSession

时间:2018-01-24 16:58:30

标签: nservicebus nservicebus6

我正在将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。 https://docs.particular.net/nservicebus/upgrades/5to6/moving-away-from-ibus 文档甚至可以避免我在MyContextAccessingDependency类的底部示例中遇到的问题。建议是通过方法传递消息上下文,该方法对在消息处理程序的上下文中运行的代码进行硬依赖。

我想要做的是访问发件人/发布者,DI容器可以给我正确的实现。代码不需要调用者的任何概念,如果它是从消息处理程序或只想发布的自托管应用程序调用的。

我看到有两个接口用于与“总线”IPipelineContext和IMessageSession进行通信,IMessageHandlerContext和IEndpointInstance接口分别扩展。 我想知道的是,两个接口的统一被NSB绑定到容器中,所以我可以接受发送/发布消息的接口。在处理程序中,它是IMessageHandlerContext,在我自己托管的应用程序中是IEndPointInstance。

目前我正在寻求根据应用程序托管更改我的IEventPublisher实现。我只是希望可能会讨论如何在没有可靠的发送/发布接口的情况下对这种方法进行建模,而不管是什么启动了代码路径的执行。

1 个答案:

答案 0 :(得分:1)

在我到达代码之前需要注意的一些事项:

  • 抽象承诺的抽象,永远不会奏效。我从未见过"我将抽象ESB / Messaging / Database / ORM的论点,以便我可以在将来交换它#34;工作。如初。

  • 当您抽象消息发送功能时,您将丢失该库提供的一些功能。在这种情况下,您无法执行对话'或使用' Sagas'这将妨碍您的整体体验,例如:在ServiceInsight中使用监控工具和观察图表时,您不会看到整个图片,只会看到通过系统的消息。

现在,为了完成这项工作,您需要在端点启动时在容器中注册IEndpointInstance。然后,该接口可用于依赖注入,例如在NsbEventPublisher中发送消息。

像这样的东西(取决于你使用的IoC容器,这里我假设是Autofac):

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

提到了使用IEndpointInstance / IMessageSession的问题here