1

2.2を使用するDynamicProxyと、この問題が発生していると思います。

「プロキシで使用できない仮想プロパティの継承可能な属性」

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プロパティを仮想ではないようにすることです。これは、私が作業しているシナリオでは実際には許容できるかもしれませんが、仮想であることが望ましいです。

ありがとう。


Patrick Steele http://weblogs.asp.net/psteele

4

2 に答える 2

2

OK、これが私が起こっていると思うことです。

問題は、派生クラスがプロパティをオーバーライドしないのIsDirtryに対し、プロキシはオーバーライドすることです。

属性は継承可能であるため、XmlIgnoreDPはそれを複製しませんが、シリアライザーはそれを気にせず、属性が複製されなかったため、プロパティをシリアル化する必要があると想定しています。

于 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 に答える