具有接口属性的MassTransit发送命令

时间:2018-05-31 07:57:38

标签: c# rabbitmq masstransit

我在我的项目中使用MassTransit,我正在尝试发送一个内部具有接口属性的命令。我将 ICreateDocumentCommand 命令中的文档属性设置为 InventoryList 。它发送它没有任何问题。但是当我收到它时,我在接收端得到一个 GreenPipes.DynamicInternal.Common.Models.IDocument

并且IDocument仅包含Document类型的属性,它没有InventoryList类的属性。基本上我只传输没有WarehouseId的Id,AuthorId和DateCreated以及所有其他属性来自InventoryList。

我的所有类都在Common.Models中,但我更喜欢使用Common.Models.InventoryList而不是IDocument。

这就是我发送命令的方式:

await endPoint.Send<ICreateDocumentCommand>(new
{
    CorrelationId = //from outside
    SocketId = //from outside
    UserName = //from outside
    UserId = //from outside
    Document = //from outside (InventoryList)
});

以下是命令定义:

public interface ICommand
{
    Guid CorrelationId { get; set; }
    Guid SocketId { get; set; }
    string UserName { get; set; }
    Guid UserId { get; set; }
}

public class Command : ICommand
{        
    public Command() {}

    public Guid CorrelationId { get; set; }
    public Guid SocketId { get; set; } 
    public string UserName { get; set; }    
    public Guid UserId { get; set; }
}

public interface ICreateDocumentCommand : ICommand
{
    IDocument Document { get; set; }
}

public class  CreateDocumentCommand : Command, ICreateDocumentCommand
{
    public CreateDocumentCommand() {}

    public IDocument Document { get; set; }
}

这是命令,现在是IDocument:

public interface IDocument
{
    Guid Id { get; set; }
    Guid AuthorId { get; set; }
    DateTime DateCreated { get; set; }
}

public class Document : IDocument
{
    public Document() {}

    public Guid Id { get; set; }
    public Guid AuthorId { get; set; }
    public DateTime DateCreated { get; set; } = DateTime.Now;
}

最后是InventoryList:

public class InventoryList : Document
{
    public InventoryList()  {}

    public Guid WarehouseId { get; set; }
    public string Copmany { get; set; }
    public Guid ResponsiblePersonId { get; set; }
    public Guid FirstCommissionMemberId { get; set; } 
    public Guid SecondCommissionMemberId { get; set; }
}

1 个答案:

答案 0 :(得分:-1)

这是一个基本的序列化问题。反序列化 ICreateDocumentCommand 时,会将 IDocument 反序列化为 IDocument -即接口。这是因为无法从接口定义中知道 IDocument 后面应该隐藏哪种具体类型。

这是一篇不错的博客文章,详细介绍了该问题和解决方案:http://appetere.com/post/serializing-interfaces-with-jsonnet

  1. 您还可以在用户上添加自定义序列化程序,以对其进行正确的反序列化,这会带来很多麻烦。

  2. 如果可以使用抽象类代替接口,那么有一个简单的解决方案。只需重新设计代码,如下所示:

    public class CreateDocumentCommand : Command, ICreateDocumentCommand
    {
         public CreateDocumentCommand()
         {
    
         }
    
         [JsonProperty(ItemTypeNameHandling = TypeNameHandling.Auto)]
         public DocumentBase Document { get; set; }
    }
    
    public abstract class DocumentBase
    {
        public Guid Id { get; set; }
    
        public Guid AuthorId { get; set; }
    
        public abstract DateTime DateCreated { get; set; }
    }
     public class Document : DocumentBase
    {
        public override DateTime DateCreated { get; set; } = DateTime.Now;
    }