代理无法获取虚拟属性的属性?

时间:2010-08-04 22:39:56

标签: c# xml-serialization castle-dynamicproxy dynamic-proxy

使用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属性不是虚拟的。在我正在使用的场景中,这实际上是可以接受的,但我更喜欢它是虚拟的。

感谢。


帕特里克斯蒂尔 http://weblogs.asp.net/psteele

2 个答案:

答案 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);
相关问题