尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Microsoft Orleans 序列化抽象包(Orleans.Serialization.Abstractions)完整指南:从特性标注到源码生成

发布时间:2026/9/25 2:14:24

资讯中心
01
ARTICLE

Microsoft Orleans 序列化抽象包(Orleans.Serialization.Abstractions)完整指南:从特性标注到源码生成

Microsoft Orleans 序列化抽象包(Orleans.Serialization.Abstractions)完整指南:从特性标注到源码生成
后端微服务【免费下载链接】orleansCloud Native application framework for .NET项目地址https://gitcode.com/gh_mirrors/or/orleans点击查看免费下载Microsoft Orleans 是面向 .NET 的云原生应用框架其核心设计之一是让普通的 .NET 类型无需继承任何基类即可在 Silo 与 Client 之间、以及 Grain 状态存储之间高效传输。Microsoft.Orleans.Serialization.Abstractions正是这条传输链路的抽象层它只负责定义序列化所需的接口与标注特性attributes不包含任何序列化实现。本文基于当前仓库源码从安装、核心特性逐一拆解、源码生成器的工作方式、到与Orleans.Serialization实现的协作关系帮助你彻底理解标记一个类可序列化背后的完整机制并掌握[GenerateSerializer]、[Id]、[Alias]等特性的正确用法与版本兼容性设计原则。1. 包定位Abstractions 与实现分离的设计1.1 什么是 Orleans.Serialization.Abstractions关联文档明确指出见 src/Orleans.Serialization.Abstractions/README.mdOrleans Serialization Abstractions package provides the core interfaces and attributes needed for Orleans serialization. This package contains the definitions used for serialization but not the serialization implementation itself.即这个包只提供定义不提供实现。它被拆分为独立程序集项目文件见 src/Orleans.Serialization.Abstractions/Orleans.Serialization.Abstractions.csproj包 ID 为Microsoft.Orleans.Serialization.Abstractions仅依赖Microsoft.Extensions.DependencyInjection.Abstractions并将README.md打包进 NuGet 作为包描述PackageReadmeFile与None IncludeREADME.md Packtrue。这种接口/标注与实现分离的意义在于编译期轻量应用与 Grain 接口项目只需引用 Abstractions 包即可使用[GenerateSerializer]、[Id]等特性无需引入完整序列化运行时实现可替换真正的序列化引擎codec、克隆器、激活器位于 src/Orleans.Serialization 程序集二者通过 DI 和源码生成器协作自动传递当你引用 Orleans Serialization 包或 Orleans SDK 时Abstractions 会自动被包含进来一般无需显式添加。1.2 如何安装关联文档给出的安装方式dotnet add package Microsoft.Orleans.Serialization.Abstractions该包会自动随Microsoft.Orleans.Serialization或 Orleans SDK 引入若你的 Grain 接口库独立于 Silo/Client 部署则显式引用此包即可获得全部序列化标注能力。2. 最小可运行示例让一个类可被序列化关联文档的核心示例使用源码生成器source generator驱动的方式using Orleans.Serialization; // Define a serializable class [GenerateSerializer] public class MyData { [Id(0)] public string Name { get; set; } [Id(1)] public int Age { get; set; } [Id(2)] public Liststring Tags { get; set; } }这个示例背后有三个关键约定均可从源码确认[GenerateSerializer]告知 Orleans 编译器插件为这个类型生成序列化代码源码见 src/Orleans.Serialization.Abstractions/Annotations.cs其定义限制目标为Class | Struct | Enum[Id(uint)]为每个被序列化成员指定一个全局唯一于该类型的数值标识序列化时只写这个 id 而非成员名这是 Orleans 实现版本容忍version-tolerant的基础——旧版本读到新版本的数据时可以跳过未知字段类无需继承任何基类、无需实现任何接口普通 POCO 即可。2.1 序列化与反序列化全流程仅标注特性还不足以让数据流动真正执行序列化的是 src/Orleans.Serialization/Serializer.cs 中的Serializer类。其核心 API 组合using Orleans.Serialization; using Microsoft.Extensions.DependencyInjection; // 创建并配置序列化器由 Orleans.Serialization 包提供 var services new ServiceCollection(); services.AddSerializer(); await using var provider services.BuildServiceProvider(); var serializer provider.GetRequiredServiceSerializer(); // 序列化到字节数组 var data new MyData { Name Alice, Age 30, Tags [a, b] }; var bytes serializer.SerializeToArray(data); // 反序列化回来 var roundTripped serializer.DeserializeMyData(bytes);从Serializer.SerializeToArray的源码可以看到其工作流程Serializer.cs从SerializerSessionPool获取一个会话session会话复用缓冲区并持有 codec 查找表通过session.CodecProvider.GetCodecT()拿到对应类型的 codec调用codec.WriteField(ref writer, 0, typeof(T), value)写入字段最终writer.Commit()并输出字节数组。Serializer还提供SerializeT(value, ref Memorybyte)、SerializeT(value, Stream, sizeHint)、Deserialize等重载以及CanSerializeT()用于探测类型是否可序列化内部调用CodecProvider.TryGetCodec见 Serializer.cs。可以推断[GenerateSerializer]生成的 codec 正是在这一查找链中被注册与使用的。3. 特性族谱Abstractions 包里的完整标注集合关联文档只展示了[GenerateSerializer]与[Id]而该包实际定义的标注远不止这两个。Annotations.cs 是包内最核心的源文件下面按用途分类展开。3.1 声明可序列化类型特性目标作用[GenerateSerializer]类/结构体/枚举要求源码生成器为该类型生成序列化代码[GenerateMethodSerializers]接口为接口生成远程调用remoting支持代码[SerializerTransparent]类声明该抽象类型对序列化不可见从继承层级中摘除仅可用于无序列化字段的抽象类型见 Annotations.cs[SuppressReferenceTracking]类生成序列化器时不对该类型做引用跟踪默认会跟踪以支持循环对象图见 Annotations.cs[OmitDefaultMemberValues]类/结构体成员值等于默认值时跳过不序列化见 Annotations.cs[Immutable]类/结构体/字段/属性/参数/返回值声明目标不可变因此永远不需要防御性深拷贝注意应用到非 sealed 类时其派生类型不保证不可变见 Annotations.cs3.2 成员标识与版本控制特性目标作用[Id(uint)]字段/属性/参数/类/结构体/枚举/方法指定成员在序列化格式中的唯一标识Annotations.cs。其备注还指出对位置记录positional record该特性可直接标注在主构造函数参数上对 RPC 方法参数显式 id 会覆盖基于 0 的参数序号且取消令牌CancellationToken参数不计入序号[Alias(string)]类/接口/结构体/枚举/方法给类型或方法指定一个well-known别名类型别名须全局唯一方法别名须在声明类型内唯一Annotations.cs[CompoundTypeAlias]类/接口/结构体/枚举以组件数组的形式组合出类型别名组件须为Type或stringAnnotations.cs[ApplicationPart]程序集将指定程序集加入 application parts供运行时发现类型Annotations.cs其中[Id]是版本容忍的关键。源码注释要求凡标注了[GenerateSerializer]的类型其每个可序列化成员都必须有一个唯一[Id]。固定数值 id而非反射成员名使得类型演进增删成员不会破坏已持久化数据或跨版本消息的解析。3.3 自动注册让自定义序列化组件被发现Orleans 允许完全自定义某个类型的序列化行为Abstractions 提供了一批注册式特性特性作用[RegisterSerializer]标注类型是序列化器应被自动注册Annotations.cs[RegisterActivator]标注类型是激活器负责创建类型实例Annotations.cs[RegisterCopier]标注类型是深拷贝器Annotations.cs[RegisterConverter]标注类型是类型转换器Annotations.cs[RegisterProvider]程序集级注册 provider如AzureTableStorage/Clustering/Server用于扩展注册Annotations.cs3.4 生命周期与调用钩子特性作用[GeneratedActivatorConstructor]标注在构造函数上告知生成的激活器在创建实例时使用该构造函数可配合依赖注入继承自ActivatorUtilitiesConstructorAttribute见 Annotations.cs[SerializationCallbacks(Type)]指定一个 hook 类型在序列化/反序列化该类型实例时被实例化并调用从IServiceProvider获取 hook 实现见 Annotations.cs[UseActivator]强制通过已注册的激活器创建实例而不是走构造函数或其他机制Annotations.cs注意[OrleansConstructor]已在源码中被标记为[Obsolete]——Use GeneratedActivatorConstructorAttribute instead. This attribute is not recognized by Orleans.Annotations.cs。新代码应使用[GeneratedActivatorConstructor]。3.5 接口与代理生成Invocation 命名空间Abstractions 还包含一组用于接口远程调用代码生成的标注位于Orleans.Invocation命名空间与Annotations.cs中[InvokeMethodName]指定 invokable 接口方法在基类型上应调用哪个方法Annotations.cs[DefaultInvokeMethodName]按返回类型为代理基类指定默认调用方法名Annotations.cs[InvokableCustomInitializer]为生成的 invokable 对象指定自定义初始化方法Annotations.cs[DefaultInvokableBaseType]/[InvokableBaseType]指定表示方法调用的 invokable 对象的基类型后者支持程序集级注册Annotations.cs[GetCompletionSourceMethodName]指定获取请求完成源completion source的方法名Annotations.cs[ReturnValueProxy]在Orleans.Invocation命名空间标注 invokable 基类型使派生类型实例直接从生成的代理方法返回而非交给运行时调用用于支持流式等非请求-响应调用模式Annotations.cs[ResponseTimeout]为接口方法指定响应超时使用TimeSpan.Parse语法Annotations.cs。3.6 接口与程序集级指令[GenerateCodeForDeclaringAssembly(Type)]指示源码生成器同时检查并生成指定类型所在程序集的代码Annotations.cs[FrameworkPart]位于Orleans.Metadata命名空间、标注程序集不包含应用代码属于内部元数据src/Orleans.Serialization.Abstractions/FrameworkPartAttribute.cs。3.7 接口定义IConverter 与 IPopulator除特性外包内还定义了两个可编程接口Annotations.cspublic interface IConverterTValue, TSurrogate where TSurrogate : struct { TValue ConvertFromSurrogate(in TSurrogate surrogate); TSurrogate ConvertToSurrogate(in TValue value); } public interface IPopulatorTValue, TSurrogate where TSurrogate : struct where TValue : class { void Populate(in TSurrogate surrogate, TValue value); }这是 Orleans surrogate代理类型机制的基础当你需要为某个第三方/不可修改的类型定制序列化时可以定义一个可序列化的结构体代理并在转换器里完成双向映射IPopulator则用于把代理值回填到既有实例而非新建实例适用于目标类型无法无参构造的场景。这些接口实现可通过[RegisterConverter]自动注册。4. 自动字段编号GenerateFieldIds 详解src/Orleans.Serialization.Abstractions/GenerateFieldIds.cs 定义了[GenerateSerializer]的GenerateFieldIds属性可选项用于控制字段 id 的自动分配枚举值行为None默认仅显式标注了[Id]的成员会被序列化PublicProperties自动为符合条件的公共属性分配字段 id条件是属性有可访问的 getter且有可访问的 setter 或对应的构造函数参数关键行为规则源码注释明确说明只要类型中有任意成员显式标注了字段 id该类型的自动编号即被整体禁用。这种要么全自动、要么全手动的规则避免了 id 冲突也让显式[Id]拥有最高优先级。示例不手写任何[Id]让生成器自动编号。[GenerateSerializer(GenerateFieldIds GenerateFieldIds.PublicProperties)] public class AutoIds { public string Name { get; set; } // 自动分配 Id(0) public int Value { get; set; } // 自动分配 Id(1) }而[GenerateSerializer]的另一个属性IncludePrimaryConstructorParameters见 Annotations.cs控制主构造函数参数是否自动作为可序列化字段参与对record类型默认true其余类型默认false。IsExternalInitsrc/Orleans.Serialization.Abstractions/Properties/IsExternalInit.cs则为旧目标框架提供init访问器支持。5. 源码生成器如何消费这些标注标注本身不产生任何序列化能力真正的代码由 src/Orleans.CodeGenerator 中的OrleansSourceGenerator生成。其处理管线从代码结构可推断大致为解析编译单元收集带[GenerateSerializer]的类型与带[GenerateMethodSerializers]的接口为每个类型生成三件套序列化器serializer、深拷贝器copier、激活器activator并注册到 DI序列化器为每个成员按[Id]或自动分配值写入字段 id 与值反序列化时按 id 分派为带[Alias]/[CompoundTypeAlias]的类型生成别名注册支持跨版本演进与类型重命名为接口生成代理proxy与 invokable 对象配合 3.5 节各标注完成远程调用管线。对应地代码生成器自身也由 DI 配置承载TypeManifestOptionssrc/Orleans.Serialization/Configuration/TypeManifestOptions.cs维护已知的Activators、FieldCodecs、Serializers、Copiers、Converters、Interfaces等集合并提供AddAllowedType/AddAllowedAssembly等配置入口。其源码注释特别提醒直接访问集合成员会破坏修剪trimming所需的信息注册组件应优先使用对应的AddXxx(Type)方法TypeManifestOptions.cs。当启用 fail-closed默认拒绝未知类型的类型验证时可通过TypeManifestOptions.AddAllowedType或AddAllowedAssembly显式放行额外的类型见 src/Orleans.Serialization/README.md。6. 版本容忍与跨版本演进实践Orleans 序列化的版本容忍是生产环境升级的关键保障其核心机制正是 Abstractions 包定义的标注字段 id 稳定[Id]一旦发布便不可更改否则旧数据/旧消息将无法正确解码允许增删字段新增字段分配新 id反序列化端会跳过未知 id删除字段则直接丢弃类型别名演进[Alias]允许你在重命名类型类名或命名空间变化后仍保持旧名称的序列化兼容性别名须全局唯一抽象类型透明化[SerializerTransparent]可将无字段的抽象中间类型从继承层级中移除但源码注释警告添加/移除该特性会导致序列化协议级不兼容效果等同类型层级变更因此同样属于发布后不可变的决策。这些能力共同支撑了 Grain 状态存储如 Azure Table、AdoNet 等持久化 provider参见 src/Azure/Orleans.Persistence.AzureStorage、src/AdoNet/Orleans.Persistence.AdoNet与跨进程消息在高频演进场景下的安全升级。7. 总结与进一步阅读Microsoft.Orleans.Serialization.Abstractions是 Orleans 序列化体系的接口与契约层它定义了[GenerateSerializer]、[Id]、[Alias]等全部标注以及IConverter/IPopulator等可编程接口却刻意不承载任何实现让源码生成器与Orleans.Serialization运行时按需生成并执行序列化逻辑。掌握本包等于掌握了 Orleans 数据如何在 .NET 分布式集群中高效、安全、可演进地流转。想要继续深入可以在当前仓库中按以下路径探索特性与接口的完整定义src/Orleans.Serialization.Abstractions/Annotations.cs、src/Orleans.Serialization.Abstractions/GenerateFieldIds.cs序列化运行时入口与 APIsrc/Orleans.Serialization/Serializer.cs、src/Orleans.Serialization/README.md类型清单与放行配置src/Orleans.Serialization/Configuration/TypeManifestOptions.cs源码生成器实现src/Orleans.CodeGenerator其中SerializerGenerator.cs、CopierGenerator.cs、ActivatorGenerator.cs分别对应三件套代码生成官方文档站点的序列化主题章节docs/site/src/content/docs 下的 serialization 相关文档。赞分享后端微服务【免费下载链接】orleansCloud Native application framework for .NET项目地址https://gitcode.com/gh_mirrors/or/orleans点击查看免费下载相关推荐Microsoft Orleans 集成 Newtonsoft.Json 序列化配置指南与源码级原理解析Microsoft Orleans 集成 Newtonsoft.Json 序列化配置指南与源码级原理解析 导读 本文围绕 src/Orleans.Serial后端微服务KernelSU 隐藏功能指南用 .ksurc 自定义 su Shell 启动环境KernelSU 隐藏功能指南用 .ksurc 自定义 su Shell 启动环境 本文是 KernelSU 隐藏功能Hidden features系列中后端微服务DB-GPT AWEL 分支算子BranchOperator完全指南条件路由 DAG 的两种实现方式与 Join 汇合实战DB GPT AWEL 分支算子BranchOperator完全指南条件路由 DAG 的两种实现方式与 Join 汇合实战 导读 BranchOperat后端微服务上一篇OpenSPG知识图谱引擎从传统图数据库到智能推理的跨越式体验下一篇终极Flexoki自定义配色教程打造你的个性化代码主题创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。