1

使用DynamicProxy2.2 我想我看到了这个问题:

“代理上不可用的虚拟属性的可继承属性”

http://support.castleproject.org/projects/DYNPROXY/issues/view/DYNPROXY-ISSUE-109

我有一个带有虚拟属性的基类。该属性标有[XmlIgnore]。如果我序列化派生类,则不会序列化该属性。但是,如果我为派生类创建代理,则该属性将被序列化。这是一个显示问题的简单控制台应用程序:

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

4

2 回答 2

2

好的,这就是我认为正在发生的事情。

问题是您的派生类不会覆盖该IsDirtry属性,而代理会。

XmlIgnore属性是可继承的,因此 DP 不会复制它,但是我猜序列化程序并不关心它,并假设由于该属性没有被复制,它应该继续并序列化该属性。

于 2010-08-05T01:23:36.587 回答
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);
于 2010-08-05T17:50:10.030 回答