Rebus RabbitMQ 对象序列化
Rebus RabbitMQ Object serialization
为什么当我通过 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
字段。这可能是 easy/hard/impossible,具体取决于您的 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());
}
}
然后剩下要做的就是创建 class YourCustomJsonSerializer
作为 ISerializer
.
的实现
为什么当我通过 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
字段。这可能是 easy/hard/impossible,具体取决于您的 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());
}
}
然后剩下要做的就是创建 class YourCustomJsonSerializer
作为 ISerializer
.