Pro*_*Dev 4 c# orleans .net-7.0
我有一个 Orleans 7.0 项目,并且我遇到了新的默认序列化器的问题。
\nOrleans 3.6.5 中的旧序列化程序运行良好,它可以序列化几个内部 Nuget 包中的所有模型和 Dtos。
\n现在在 Orleans 7.0 中,该项目无法识别 Nuget 包中的模型,并且出现以下错误:
\nOrleans.Serialization.CodecNotFoundException: Could not find a copier for type InternalProject.Model.\n\xc2\xa0\xc2\xa0 at Orleans.Serialization.Serializers.CodecProvider.ThrowCopierNotFound(Type type) in /_/src/Orleans.Serialization/Serializers/CodecProvider.cs:line 666\n\xc2\xa0\xc2\xa0 at Orleans.Serialization.Serializers.CodecProvider.GetDeepCopier[T]() in /_/src/Orleans.Serialization/Serializers/CodecProvider.cs:line 300\n\xc2\xa0\xc2\xa0 at Orleans.Serialization.ServiceCollectionExtensions.CopierHolder`1.get_Value() in /_/src/Orleans.Serialization/Hosting/ServiceCollectionExtensions.cs:line 203\n\xc2\xa0\xc2\xa0 at Orleans.Serialization.GeneratedCodeHelpers.OrleansGeneratedCodeHelper.GetService[TService](Object caller, ICodecProvider codecProvider) in /_/src/Orleans.Serialization/GeneratedCodeHelpers/OrleansGeneratedCodeHelper.cs:lin\ne 75\n\xc2\xa0\xc2\xa0 at OrleansCodeGen.InternalProject.Model.Copier_SpecificModel..ctor(ICodecProvider codecProvider) in C:\\Projects\\InternalProject.Model\\Orleans.CodeGenerator\\Orleans.CodeGenerator.Orle\nansSerializationSourceGenerator\\InternalProject.Model.orleans.g.cs:line 20736\n\xc2\xa0\xc2\xa0 at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)\n\xc2\xa0\xc2\xa0 at System.Reflection.ConstructorInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)\n\xc2\xa0\xc2\xa0 at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)\n\xc2\xa0\xc2\xa0 at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)\n\xc2\xa0\xc2\xa0 at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters)\n\xc2\xa0\xc2\xa0 at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetServiceOrCreateInstance[T](IServiceProvider provider)\n\xc2\xa0\xc2\xa0 at Orleans.Serialization.GeneratedCodeHelpers.OrleansGeneratedCodeHelper.GetService[TService](Object caller, ICodecProvider codecProvider) in /_/src/Orleans.Serialization/GeneratedCodeHelpers/OrleansGeneratedCodeHelper.cs:lin\ne 72\nRun Code Online (Sandbox Code Playgroud)\n现在有趣的部分是:当我在主项目中复制粘贴完全相同的类时,我不再收到此错误,并且该类序列化得很好。
\n我尝试在主项目(ProjectReference)中直接引用Nuget项目,结果是一样的。
\n我只在两种情况下消除错误:
\nsiloBuilder.Services.AddSerializer(sb =>\n {\n sb.AddJsonSerializer(\n isSupported: type => type.Namespace.StartsWith("Nuget.Namespace"),\n new JsonSerializerOptions()\n {\n ReferenceHandler = ReferenceHandler.IgnoreCycles\n }\n );\n });\nRun Code Online (Sandbox Code Playgroud)\n[GenerateSerializer]\n public sealed class Class1: Class1Base\n {\n public Class1()\n {\n \n }\n\n public Class1(IRequest request, bool boolean, InternalClass internalClass) \n : base(request, boolean)\n {\n InternalClass = internalClass;\n }\n\n [Id(0)]\n public InternalClass InternalClass{ get; set; }\n \n }\n\n [GenerateSerializer]\n public class Class1Base\n {\n public Class1Base()\n {\n \n }\n public Class1Base(IRequest request, bool boolean)\n {\n Request = request;\n Boolean= boolean;\n }\n\n [Id(0)]\n public IRequest Request { get; set; }\n [Id(1)]\n public bool Boolean{ get; set; }\n }\nRun Code Online (Sandbox Code Playgroud)\n
小智 5
Orleans 序列化器具有很多性能和灵活性优势,但正如您所发现的,它在使用第 3 方类型方面具有非常硬的优势。你有几个选择,但都不是很好
继续使用第 3 方类型并为您将序列化的每种类型定义代理和编解码器。这可能是一项非常繁重的工作,而且可能不是最好的主意。请参阅此文档了解如何执行此操作,但请注意,如果您不小心错过了图中的类型,它会在运行时崩溃,因此请确保您的测试良好。
使用不同的序列化器。Orleans 附带了基于 Json 的序列化器,更容易使用。它们可能不如 Orleans Serializer 快,但运行起来要简单得多。这是最简单的选择,而且几乎没有什么缺点。请参阅这篇文章了解如何执行此操作
从 DTO 中删除第 3 方类型。在此选项中,您可以更改grain合约,以便仅使用第一方类型(您自己定义的类型)在grain之间发送消息。这不太方便,并且消除了奥尔良对象透明度的一些魔力,但消除了问题。这是我在我的案例中选择的选项,因为我认为它可以使我的模型保持干净。
我还怀疑,通过大量的努力,可能可以编写一个源生成器,它可以自动遍历grain调用中使用的对象图,并自动生成第三方类型的编解码器和代理,以完全消除这个问题。但我觉得没有必要。
| 归档时间: |
|
| 查看次数: |
1388 次 |
| 最近记录: |