2

似乎我不能多次定义命令/事件约定。每个注册的约定都将覆盖以前的约定。

这有效:

 configuration.Conventions()
            .DefiningCommandsAs(
                type => type.FullName == "MyProject1.CommandA" || type.FullName == "MyProject2.CommandB");

但这不会:

        configuration.Conventions()
            .DefiningCommandsAs(
                type => type.FullName == "MyProject1.CommandA");

        configuration.Conventions()
            .DefiningCommandsAs(
                type => type.FullName == "MyProject2.CommandB");

为什么我需要这个:

我正在开发一个曾经在 NSB 项目中引用的包,它将执行定期操作(发送消息)。它需要定义自己的命令约定,INeedInitialization在程序集扫描期间将采用这些约定。我不希望包的用户知道他需要注册包的约定。但是宿主项目需要为命令注册自己的约定。因此,目前看来我要么需要求助于标记接口(我不想这样做,引入不显眼模式是有充分理由的),要么提出所有命令必须驻留在 *.Commands 中的约定。 * 我也不喜欢的命名空间。

所以问题是如何让包注册它自己的约定对主机不显眼和透明。

编辑

我可以想到解决此问题的另一种方法是实现共享约定单例并将约定的注册委托给它。然后,该单例将记住所有约定,并且每次都会继续附加它们。不漂亮,但不比其他 2 个选项丑。

4

1 回答 1

5

不支持多次调用的消息约定绝对是设计使然。这是为了防止对消息的含义有多种意见。让它们具有附加性意味着任何人都可以发表意见。

因此,此模式旨在提供针对这一点的摩擦,让您就Command在整个系统中的含义达成一致。基本上,SOA 原则 #4:服务兼容性基于策略。很多时候,这是“以”结尾的命名空间.Commands模式;我个人用过那个,效果很好。

我确实为 Particular 工作,所以虽然没有什么是一成不变的,但我可以相当自信地说 V6 中没有改变这一点的计划。

如果您绝对需要做一些不同的事情,那么您在编辑中创建某种MessageRegistry单例并拥有约定委托的想法MessageRegistry.IsCommand(Type)是完全有效的。在 V5 中,在总线启动之前不会执行任何操作,因此只要在总线启动之前填充 MessageRegistry(这也可以从内部完成INeedInitialization),那么一切都应该很好。

如果您确实走这条路,我鼓励您一路走下去,让您的注册表单例负责其他元数据,例如 TimeToBeReceived、DataBus、WireEncryptedString、Express,以及任何其他基于属性的消息元数据。

于 2015-12-10T20:01:40.410 回答