包装NServiceBus.IHandleMessages

Mar*_*ler 7 nservicebus3

我被要求开发将作为通用总线不采取行动一层任何以NServiceBus直接引用.到目前为止,由于对不显眼的消息的支持并不是太难.除了现在我已被要求提供我们自己的IHandleMessages定义,并找到一种在连线过程中映射它的方法.所以我在想这样的事情:

    public class MessageHandlerAdapter<T> : IHandleMessages<T>
{
    IUnityContainer container;

    public MessageHandlerAdapter(IUnityContainer container)
    {
        this.container = container;
    }

    #region IMessageHandler<T> Members

    public void Handle(T message)
    {
        var handler = container.Resolve<IHandle<T>>();
        handler.Handle(message);
    }

    #endregion
}
Run Code Online (Sandbox Code Playgroud)

IHandle将成为我们自己的定义(顺便说一下,它与IHandleMessages完全相同).我希望能够反映AppDomain并找到所有实现IHandle的类并将它们注册到容器中,然后注册一个具有相同类型T的MessageHandlerAdapter.

我的问题是我已经使用NServiceBus将近2年了,我不记得在NSB管道中将这种功能挂钩到哪里.

Sim*_*mon 42

您可能不喜欢这个答案但是......不要为您使用的工具编写抽象层.

我见过许多人试图围绕某些工具编写抽象层的实例.主要是案例是日志记录和ORM框架.现在,当他们这样做时,人们就有了良好的愿望.他们希望"能够轻松切换库X".不幸的是,由于几个原因,这是一个坏主意

  • 不相容的概念.在您的示例中,您可能会提取出NSB Saga超时的概念.然而,无法保证这个概念在理论上的"图书馆转向未来"中的行为方式相同,或者概念将存在.通常这些"抽象层"最终成为单个库的直接映射,并且根本不可移植.
  • 增加复杂性.您将为解决方案添加大量复杂性.
  • 样品不会起作用.当你查看库的样本时,你需要"映射到你的"到你的抽象层
  • 进入障碍.虽然加入您团队的新开发人员可能已经使用了相关库,但他们将无法理解您的包装器
  • 与API抗争.没有设计过具有"能够提取通用实现"功能的库.因此,API会主动打击您执行此活动.
  • 调试.额外的层将使调试解决方案变得更加困难
  • 性能.通常,更多的代码是更慢的代码.通常这些抽象层也需要使用反射......
  • 支持.您将更难获得拥有该库的人员的支持,因为很难记录您与库的交互方式.
  • 正在进行的变革.每次有问题的库添加或更改API时,您必须先添加映射代码,然后才能在解决方案中利用该功能.
  • 文档.通常需要花费大量的人力来为图书馆创建文档.对您而言,将抽象的文档提升到该级别将是一项重大的工作.

这一切都归结为时间.您正试图花时间抽象该工具.期望在未来节省更多的时间.问题是,如果您决定切换,您将花费更多时间来创建和维护此抽象.这应该是您对同事的回应.

这是一篇来自Ayende的有趣文章,讲述了抽象的弊端.其中大部分适用于这种情况http://ayende.com/blog/4784/architecting-in-the-pit-of-doom-the-evils-of-the-repository-abstraction-layer引用

...尽量避免不必要的复杂性...添加额外的抽象层通常只会让它变得困难.

  • _不要写抽象层_ - 什么废话.您认为Unity3D的制造商做了什么?WCF本身可以很好地抽象出可以说是不兼容的概念,例如排队和非排队的消息; 流式和非流式数据都使用单个API.如果它不适用于WCF,我们将有一个用于远程处理的API和另一个用于TCP/IP的API.因此,无论细节程度如何,抽象都会在我的书中发挥作用. (2认同)