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 中真的不同吗?的主要内容,如果未能解决你的问题,请参考以下文章
Spring Framework Part3 IoC and Dynamic Proxy
为啥 Castle Windsor 拦截器会破坏 C# 动态对象上方法的运行时绑定?
Castle Windsor 3 + Fluent NHibernate + Castle.NHibernate.Integration