NServiceBus创建消息具有反直觉具体类型实现,需要繁琐的类型转换

NServiceBus创建消息具有反直觉具体类型实现,需要繁琐的类型转换,nservicebus,Nservicebus,NServiceBus创建从接口到用作消息的具体实现类。这在理论上是为了允许这些消息与其他消息的组合。实际上允许多重继承。为了演示不一致的行为,我创建了几个测试接口: public interface ITestBase1 { string Property1 { get; set; } } public interface ITestBase2 : ITestBase1 { } public interface ITestBase3 : ITestBase2 { } 然后我运

NServiceBus创建从接口到用作消息的具体实现类。这在理论上是为了允许这些消息与其他消息的组合。实际上允许多重继承。为了演示不一致的行为,我创建了几个测试接口:

public interface ITestBase1
{
    string Property1 { get; set; }
}

public interface ITestBase2 : ITestBase1
{

}

public interface ITestBase3 : ITestBase2
{

}
然后我运行了以下代码:

var types = new[] { typeof(ITestBase1) };

new NServiceBus.MessageInterfaces.MessageMapper.Reflection.MessageMapper().Initialize(types);

var msg = new NServiceBus.MessageInterfaces.MessageMapper.Reflection.MessageMapper().CreateInstance(typeof(ITestBase1));
如果我创建ITestBase1的具体实现,我会找到我所期望的。一种称为Property1的属性。如果我创建ITestBase2的具体实现,我发现msg有一个Property1属性

但是,如果我创建ITestBase3的具体实现,我会在msg对象上得到两个Property1的实现。一个用于ITestBase1,一个用于ITestBase2接口。这对我来说似乎有点违反直觉。我希望基本消息上Property1实现的数量不会变化。这使得在试图用组件构建消息时非常混乱


除了修改nservicebus的messagemapper.GetAllProperties代码之外,还有其他方法可以避免这种行为吗?我不希望其他接口创建相同数据类型和名称的新属性。

我对具体实现的目的的理解是:

  • 因此,订阅服务中不需要实现,并且
  • 要方便地创建简单消息,例如:

    Bus.Publish(m=>{m.Property1=“我的值”;})


  • 我正在努力设想一个场景,您需要直接创建自己的实例。你能详细说明一下你在这里做什么吗?

    这可能是一个VS错误。我的层次结构如下:IPProductCreateDevent:IPProductChangeDevent:IEEvent:IMessage。使用您的代码,我在VS调试器中看到您描述的行为:

    但如果对类型进行反思,则属性将正确显示:


    如果我强制转换为IEvent并设置属性,那么一切都会按预期工作。因此,无论调试器显示什么,运行时都能正确地查看类型,因此您可以继续以这种方式对消息建模

    “使用接口的另一个原因是它们支持多重继承,这对于在不中断现有订阅者的情况下将系统从一个版本扩展到下一个版本非常有用。“在这种情况下,我只是描述由nservicebus创建的具体类需要您仔细地进行转换。如果接口A派生自B,则派生自C。C在B和C类中创建为单独支持的属性。Set(项为B)。Property1=1,而您尚未设置(项为C).Property1。后者仍未定义。nservicebus为您创建的具体类可能会严重混淆继承人体系结构深度超过两级的位置。这与上述文档中的引用相反。如果您发布的是版本化消息,我希望您希望创建自己的实现。非平凡版本NGE可能无论如何都需要自定义代码来支持以前的版本。版本化邮件的订阅者应该只与他们订阅的特定版本进行交互。我仍然不确定为什么需要强制转换邮件?您使用的是哪个版本的NSB?我刚刚在2.0.0.1219上尝试了此操作,但只获得了1个属性。这个问题em现在已经在即将到来的2.5版本以及主/主干上修复。