我似乎不能多次定义命令/事件约定。每一个已登记的公约都将取代以前的公约。
这项工作:
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
中定义自己的命令约定,这些约定将在程序集扫描期间拾取。我不想让包的用户知道他需要注册包的约定。但是,宿主项目需要注册自己的命令约定。因此,目前我似乎要么需要求助于Marker接口(我不想这样做,引入Unobtrusive模式是有充分理由的),要么提出所有命令都必须位于*.commands.*命名空间之类的约定,我也不喜欢。
因此,问题是如何让程序包注册它自己的约定,对主机来说既不引人注目又透明。
编辑
我可以想到的另一种破解方法是实现一个共享约定的singleton,并将约定的注册委托给它。然后这个singleton会记住所有约定,并每次都会添加它们。不漂亮,但不比其他2种选择更丑。
不支持多个调用的消息约定肯定是经过设计的。这是为了防止对一条信息可能是什么有多种意见。将它们相加意味着任何人都可以有意见。
因此,这种模式旨在提供摩擦,让您就Command在整个系统中的含义达成一致。基本上,SOA信条#4:服务兼容性是基于策略的。很多时候,这是"以.Commands
结尾的命名空间"模式;我个人用过这个,效果很好。
我确实为Special工作,所以虽然没有什么是一成不变的,但我可以有信心地说,V6中没有改变这一点的计划。
如果您绝对需要做一些不同的事情,那么您在Edit中创建某种MessageRegistry
单例并将约定委托给MessageRegistry.IsCommand(Type)
的想法是完全有效的。在V5中,在总线启动之前不会执行任何操作,因此只要在总线启动前填充MessageRegistry(也可以在INeedInitialization
中完成),那么一切都应该很好。
如果你真的走上了这条路,我鼓励你一直走下去,让你的注册表单例负责其他元数据,如TimeToBeReceived、DataBus、WireEncryptedString、Express,以及任何其他基于属性的消息元数据。