具有基类型

时间:2015-10-13 12:08:34

标签: .net wcf nservicebus

我们开发了一个WCF Web服务,其合同类似于以下内容:

[ServiceContract(Namespace = "XXX")]
public interface ISynchronization
{
    [OperationContract(IsOneWay = true)]
    void ProcessEntities(List<BaseEntity> entities);
}

通过在配置文件中knowntypes下使用BaseEntity datacontractserializer配置,它可以很好地工作并且很容易扩展。

现在需要使用NServiceBus的可靠消息传递,我需要提供适当的消息格式,能够以通用方式传输实体。

我是NServiceBus的新手,但是从我所理解的情况来看,默认的NSB序列化器不会关注多态性,而且我仍然坚持使用command-per-实体场景。

上面提到的不是任何类型的车轮改造,必须有一个优雅的解决方案。

使用DataContractSerializer而不是NSB的原生代码有什么可能的缺点?

编辑(继承测试作为对拉蒙的回答)

我已使用其中一个NSB test projects并更改了CancelOrder,如下所示:

public class CancelOrder : IMessage
{
    public int OrderId { get; set; }
    public List<EntityBase> Entities { get; set; }
}

[KnownType(typeof(Employee))]
[KnownType(typeof(Organization))] //Serialization fails otherwise
public class EntityBase
{
    public virtual string Name { get; set; }
}

public class Employee : EntityBase {
    public override string Name {get{ return "Employee"; }}
    public string EmployeeProperty {get{ return "Employee Property Value"; }}
}

public class Organization : EntityBase
{
    public override string Name {get{ return "Organization"; }}
    public string OrganizationProperty {get { return "Organization Property Value"; }}
}

EntityBase(不抽象 - 也会使序列化制动)具有单个虚拟属性Name,以便于测试。

测试客户端正在发送CancelOrder个实体列表,其中填充了EmployeeOrganization

 var message = new CancelOrder
               {
                 OrderId = orderId++,
                 Entities = new List<EntityBase>
                 {
                   new Employee(), 
                   new Organization()
                 }
               };

 var returnCode = client.Process(message);

一旦投放到服务器,它们就不再是EntityBase种类型(message.Entities[0] as Employee == null

Quick Watch at the Server

1 个答案:

答案 0 :(得分:2)

您的界面可以翻译为以下消息:

public class SynchronizeCommand : IMessage
{
    public int OrderId { get; set; }
    public List<EntityBase> Entities { get; set; }
}

[KnownType(typeof(Employee))] // Required for WCF, not the Json serializer
[KnownType(typeof(Organization))]
public class EntityBase
{
    public virtual string Name { get; set; }
}

public class Employee : EntityBase {
    public override string Name {get{ return "Employee"; }}
    public string EmployeeProperty {get{ return "Employee Property Value"; }}
}

public class Organization : EntityBase
{
    public override string Name {get{ return "Organization"; }}
    public string OrganizationProperty {get { return "Organization Property Value"; }}
}

NServiceBus XML序列化程序无法对此进行序列化,但Json序列化程序可以进行序列化。

您提到的多态性限制是关于消息类型而不是其属性。

如果您希望在要触发的处理程序类型中使用多态行为,则不能对类使用多重继承。只允许接口,因为它们是唯一允许多重继承的类型。

数据合同序列化器缺点

  • 无法序列化接口,需要一个类
  • 您需要在所有端点上使用DataContractSerializer
  • NServiceBus序列化程序不太灵活,无法简化邮件合同
  • XML不太可读

数据合同序列化专业人员

  • 更适合整合目的
  • 支持复杂数据,例如带有循环引用的图表