You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Orleans 7.0默认序列化器无法处理NuGet包中的POCO类

Orleans 7.0 序列化器无法识别内部NuGet包模型的解决方案

问题重现

升级Orleans至7.0后,默认序列化器无法处理内部NuGet包中的模型与DTO,抛出CodecNotFoundException错误;但将模型类直接复制到主项目、或改用带IgnoreCycles的Json序列化器时,问题消失。即使直接引用模型项目(ProjectReference),错误依然存在。

错误日志示例:

Orleans.Serialization.CodecNotFoundException: Could not find a copier for type InternalProject.Model.
   at Orleans.Serialization.Serializers.CodecProvider.ThrowCopierNotFound(Type type) in /_/src/Orleans.Serialization/Serializers/CodecProvider.cs:line 666
   ...(省略后续堆栈信息)

根本原因

Orleans 7.0默认使用源生成式序列化器,替代了旧版本的运行时序列化。若模型项目未正确配置代码生成、或NuGet包未包含生成的序列化代码,主项目无法识别模型的序列化器/复制器,从而抛出异常。

解决步骤

1. 配置模型项目启用序列化源生成

在生成NuGet包的模型类库项目(.csproj)中添加以下配置:

<PropertyGroup>
  <!-- 启用Orleans序列化代码生成 -->
  <OrleansSerializationCodeGeneration>true</OrleansSerializationCodeGeneration>
</PropertyGroup>

<ItemGroup>
  <!-- 引入序列化与代码生成包,设置PrivateAssets避免传递引用 -->
  <PackageReference Include="Orleans.Serialization" Version="7.0.*" PrivateAssets="all" />
  <PackageReference Include="Orleans.CodeGenerator.MSBuild" Version="7.0.*" PrivateAssets="all" />
</ItemGroup>

2. 检查模型的序列化属性完整性

确保所有需要序列化的类型(包括基类、嵌套类、接口实现类)都正确标记:

  • 类必须添加[GenerateSerializer]特性
  • 需序列化的属性必须添加[Id(n)]特性(n为唯一整数ID,从0开始递增)
  • 接口IRequest的具体实现类也必须标记[GenerateSerializer],Orleans无法直接序列化接口类型

示例正确标记的类:

[GenerateSerializer]
public sealed class Class1 : Class1Base
{
    public Class1() { }

    public Class1(IRequest request, bool flag, InternalClass internalClass) 
        : base(request, flag)
    {
        InternalClass = internalClass;
    }

    [Id(0)]
    public InternalClass InternalClass { get; set; }
}

[GenerateSerializer]
public class Class1Base
{
    public Class1Base() { }

    public Class1Base(IRequest request, bool flag)
    {
        Request = request;
        BooleanFlag = flag;
    }

    [Id(0)]
    public IRequest Request { get; set; }
    [Id(1)]
    public bool BooleanFlag { get; set; }
}

// 嵌套类也需要正确标记
[GenerateSerializer]
public class InternalClass
{
    [Id(0)]
    public string Data { get; set; }
}

// IRequest的实现类必须标记
[GenerateSerializer]
public class RequestImpl : IRequest
{
    [Id(0)]
    public string Id { get; set; }
}

3. 确保NuGet包包含源生成代码

在模型项目的.csproj中添加配置,将源生成的.orleans.g.cs文件打包进NuGet:

<ItemGroup>
  <!-- 将源生成的序列化代码包含到NuGet包中 -->
  <Compile Include="**/*.orleans.g.cs" Pack="true" PackagePath="lib/$(TargetFramework)" />
</ItemGroup>

4. 主项目显式注册模型程序集

在Silo或Client的配置代码中,注册模型所在的程序集,让Orleans扫描并加载序列化器:

// Silo配置示例
var siloBuilder = new SiloBuilder()
    .ConfigureServices(services =>
    {
        services.AddOrleansSerialization(builder =>
        {
            // 注册模型所在的程序集
            builder.AddAssembly(typeof(Class1).Assembly);
        });
    })
    // 或通过ApplicationParts注册
    .AddApplicationParts()
    .AddAssembly(typeof(Class1).Assembly);

5. 清理重建项目

  • 删除所有项目的bin、obj目录
  • 清理NuGet缓存:执行dotnet nuget locals all --clear
  • 重新生成模型项目并打包NuGet
  • 主项目更新NuGet引用后重新编译

验证

完成以上步骤后,主项目引用NuGet包中的模型时,Orleans默认序列化器可正常生成复制器与序列化器,不再抛出CodecNotFoundException。

内容的提问来源于stack exchange,提问作者Professional_Amateur_Dev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 05:25:53