Rebus RabbitMQ 对象序列化



当我通过 rebus 向 RabbitMQ 发送一条消息时,为什么它会添加额外的对象数据,如下所示,主要是$type。

{"$type":"ThreeSquared.VTGPAM.Objects.Wagon, ThreeSquared.VTGPAM.Objects","WagonId":"a98a06ab-33b9-4a11-9de2-df0b8787b713","WamosId":12324,"Description":"test","YearBuilt":1982,"Token":"3cce443c-249f-4fd2-9882-5830fb308b6b"}

我们有一个客户端,它只使用 Java RabbitMQ 库,没有 rebus。我相信这种方法我们只发送 JSON 而不发送类型声明。因此,当我尝试读取简单的 JSON 对象时,这不起作用。我们如何让它工作,以便它不会定义消息中的$type?

这仅仅是因为 Rebus 默认使用 Newtonsoft JSON.NET 和TypeNameHandling.All,这意味着$type字段包含在每个序列化对象中,其中包含序列化类型的完整 .NET 类型名称。

好处是,您几乎可以序列化任何内容,即使它可能包含由(可能是抽象的(超类型甚至接口引用的实例。

例如,此命令消息类型

public class ProcessFile
{
public ProcessFile(string filePath, IEnumerable<IFileProcessingTask> tasks)
{
FilePath = filePath;
Tasks = tasks;
}
public string FilePath { get; }
public IReadOnlyCollection<IFileProcessingTask> Tasks { get; }
}

可以包含IFileProcessingTask的任意实现,例如类似

public class GZipFileProcessingTask : IFileProcessingTask
{
// ...    
}

只要收件人可以通过$type字段的值查找类型来找到类型。

如果要在另一个平台上处理此类消息,只需使其忽略每个对象的$type字段即可。这可能很容易/很难/不可能,具体取决于 JSON 序列化程序的灵活性。

另一种选择是简单地将 Rebus 的序列化程序替换为您自己的实现

,方法是这样做
Configure.With(...)
.(...)
.Serialization(s => s.UseCustomJsonSerialization())
.Start();

其中UseCustomJsonSerialization是像这样实现的扩展方法:

public static class RebusConfigEx
{
public static void UseCustomJsonSerialization(this StandardConfigurer<ISerializer> configurer)
{
configurer.Register(c => new YourCustomJsonSerializer());
}
}

然后剩下要做的就是创建类YourCustomJsonSerializer作为ISerializer的实现。

最新更新