1

我正在将 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 容器可以给我正确的实现。代码不需要调用者的任何概念,如果它是从消息处理程序调用的,还是从只想发布的自托管应用程序调用的。

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

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

4

1 回答 1

1

在我进入代码之前需要注意一些事项:

  • 对抽象承诺的抽象永远不会奏效。我从未见过“我将抽象 ESB/Messaging/Database/ORM 以便将来可以交换它”的论点。曾经。

  • 当您像这样抽象消息发送功能时,您将失去该库提供的一些功能。在这种情况下,您不能执行“对话”或使用“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 的问题。

于 2018-01-25T07:19:06.640 回答