使用DynamicProxy
2.2我认为我看到了这个问题:
“代理上不可用的虚拟属性上的可继承属性”
http://support.castleproject.org/projects/DYNPROXY/issues/view/DYNPROXY-ISSUE-109
我有一个带有虚拟属性的基类。该属性标有[XmlIgnore]
。如果我序列化派生类,则不会序列化该属性。但是,如果我为派生类创建代理,则属性IS已序列化。这是一个显示问题的简单控制台应用程序:
using System;
using System.Xml.Serialization;
using Castle.DynamicProxy;
namespace ConsoleApplication1
{
class Program
{
static void Main()
{
var derived = new Derived { IsDirty = true, Sample = "ABC"};
derived.Save();
Console.WriteLine("\n\nProxied...\n");
var generator = new ProxyGenerator();
var derivedProxy = generator.CreateClassProxy<Derived>();
derivedProxy.IsDirty = true;
derivedProxy.Sample = "ABC";
derivedProxy.Save();
Console.WriteLine("\n\n");
Console.ReadKey();
}
}
public abstract class Base
{
[XmlIgnore]
public virtual bool IsDirty { get; set; }
public virtual void Save()
{
var ser = new XmlSerializer(this.GetType());
ser.Serialize(Console.Out, this);
}
}
public class Derived : Base
{
public virtual string Sample { get; set; }
}
}
这是一个错误吗?或者我做错了什么。快速解决方法是使我的IsDirty
属性不是虚拟的。在我正在使用的场景中,这实际上是可以接受的,但我更喜欢它是虚拟的。
感谢。
答案 0 :(得分:2)
好的,这就是我认为正在发生的事情。
问题是您的派生类不会覆盖IsDirtry
属性,而代理会这样做。
XmlIgnore
属性是可继承的,因此DP不会复制它,但是我猜测序列化程序并不关心它,并且假设由于该属性未被复制,它应该继续并序列化该属性。
答案 1 :(得分:1)
我想在今天找到一些东西。我也可以使用代理生成钩子来跳过这个特定属性的代理:
public class SkipIsDirtyProxying: IProxyGenerationHook
{
public void MethodsInspected()
{
}
public void NonVirtualMemberNotification(Type type, System.Reflection.MemberInfo memberInfo)
{
}
public bool ShouldInterceptMethod(Type type, System.Reflection.MethodInfo methodInfo)
{
if (methodInfo.Name == "set_IsDirty" || methodInfo.Name == "get_IsDirty")
{
return false;
}
return true;
}
}
然后在创建代理生成器时使用此挂钩:
var generator = new ProxyGenerator();
var options = new ProxyGenerationOptions(new SkipIsDirtyProxying());
var derivedProxy = generator.CreateClassProxy<Derived>(options);