代码之家  ›  专栏  ›  技术社区  ›  PatrickSteele

代理不获取虚拟属性的属性?

  •  1
  • PatrickSteele  · 技术社区  · 15 年前

    使用 DynamicProxy 2.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

    2 回复  |  直到 10 年前
        1
  •  2
  •   Krzysztof Kozmic    15 年前

    好吧,我想是这样的。

    问题是派生类没有重写 IsDirtry 属性,而代理是。

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

        2
  •  1
  •   PatrickSteele    15 年前

    只是想给我今天发现的东西添点什么。我还可以使用代理生成钩子跳过此特定属性的代理:

    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);