【问题标题】:Is Castle Dynamic Proxy IInvocation really different in .net Core and Framework?Castle Dynamic Proxy IInvocation 在 .net Core 和 Framework 中真的不同吗?
【发布时间】:2023-03-21 10:20:01
【问题描述】:

我的代码使用 Castle DynamicProxy 来代理代码调用。在 Intercept(IInvocation invocation) 中,我使用 NewtonSoft 对调用进行 Json 序列化。

Newtonsoft.Json.JsonConvert.SerializeObject(invocation.Method);

在框架中,这会产生一个非常简洁的东西,如下所示:

{
"Name": "FastLoadDataAsJson",
"AssemblyName": "TinyData, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
"ClassName": "Dimension2.Core.Database.TinyData",
"Signature": "Byte[] FastLoadDataAsJson(System.String, System.String, System.String)",
"Signature2": "System.Byte[] FastLoadDataAsJson(System.String, System.String, System.String)",
"MemberType": 8,
"GenericArguments": null
}

在 .Net Core 项目中,相同的序列化调用首先给出此异常:

检测到类型为“System.Reflection.RuntimeModule”的属性“ManifestModule”的自引用循环。路径'Module.Assembly'。'

我可以使用设置 Newtonsoft.Json.ReferenceLoopHandling.Ignore 绕过它

但我返回的 JSON 有 93,000 行长!!!这到底是怎么回事?调用似乎完全不同。除了长度之外,属性也不同,例如没有 Signature 或 Signature2 属性。

框架简洁的 Json 似乎完全适合描述我们需要进行的调用。那么为什么Core如此不同呢?我担心我遗漏了有关 Castle、Core 或两者的重要信息。

【问题讨论】:

    标签: .net .net-core json.net castle-dynamicproxy binary-serialization


    【解决方案1】:

    IInvocation.Method 属性的类型为 System.Reflection.MethodInfo,使用 JSON.NET 序列化该对象的 JSON 与 Castle Core 无关。

    查看 .NET Framework 的序列化功能可以了解 JSON.NET 从何处获取这些功能。 .NET Core 不支持二进制序列化,因此 JSON.NET 将使用其通常的公共属性序列化,导致它遇到循环引用。

    [Serializable]
    internal class MemberInfoSerializationHolder : ISerializable, IObjectReference 
    {
        //...
        public static void GetSerializationInfo(
            SerializationInfo info,
            String name,
            RuntimeType reflectedClass,
            String signature,
            String signature2,
            MemberTypes type,
            Type[] genericArguments)
        {
            if (info == null)
                throw new ArgumentNullException("info");
            Contract.EndContractBlock();
    
            String assemblyName = reflectedClass.Module.Assembly.FullName;
            String typeName = reflectedClass.FullName;
    
            info.SetType(typeof(MemberInfoSerializationHolder));
            info.AddValue("Name", name, typeof(String));
            info.AddValue("AssemblyName", assemblyName, typeof(String));
            info.AddValue("ClassName", typeName, typeof(String));
            info.AddValue("Signature", signature, typeof(String));
            info.AddValue("Signature2", signature2, typeof(String));
            info.AddValue("MemberType", (int)type);
            info.AddValue("GenericArguments", genericArguments, typeof(Type[]));
        }
        //...
    }
    

    (https://referencesource.microsoft.com/#mscorlib/system/reflection/memberinfoserializationholder.cs)

    【讨论】:

      猜你喜欢
      • 2011-10-03
      • 1970-01-01
      • 2013-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-18
      • 2011-04-26
      相关资源
      最近更新 更多