Castle Dynamic Proxy IInvocation 在 .net Core 和 Framework 中真的不同吗?

Posted

技术标签:

【中文标题】Castle Dynamic Proxy IInvocation 在 .net Core 和 Framework 中真的不同吗?【英文标题】:Is Castle Dynamic Proxy IInvocation really different in .net Core and Framework? 【发布时间】:2020-04-10 15:21:40 【问题描述】:

我的代码使用 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 或两者的重要信息。

【问题讨论】:

【参考方案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)

【讨论】:

以上是关于Castle Dynamic Proxy IInvocation 在 .net Core 和 Framework 中真的不同吗?的主要内容,如果未能解决你的问题,请参考以下文章

Java的动态代理(dynamic proxy)

Java的动态代理(dynamic proxy)

动态代理Dynamic Proxy

Spring Framework Part3 IoC and Dynamic Proxy

为啥 Castle Windsor 拦截器会破坏 C# 动态对象上方法的运行时绑定?

Castle Windsor 3 + Fluent NHibernate + Castle.NHibernate.Integration