0

すべての WCF パラメータをファイルに記録したいと思います。パラメータ インスペクターを使用し、すべての入力のすべてのクラスのすべてのプロパティを検査するための再帰コードを作成します (私のコードは次のようなものです:リフレクションを使用してオブジェクトのプロパティの値を再帰的に出力する方法)。次のようなファイルにログインできます。

MethodName(string="aaa", ComplexClass=[prop="aaa", prop2="bbb"])

残念ながら、NoLog というカスタム属性でマークされたプロパティをログに記録しないようにコードを変更する必要があります。すべてのプロパティの属性を取得するようにコードを変更しましたが、パラメーターを検査するたびにコードが本当に遅くなるためです。

私の質問は次のとおりです。キャッシュを提供するにはどうすればよいですか?

4

1 に答える 1

3

いくつかのクラスがあります:

public class A
{
    public int Id { get; set; }
    public B BValue { get; set; }

    public A()
    {
        this.Id = 1000;
        this.BValue = new B();
    }
}

public class B
{
    public string Name { get; set; }
    public C CValue { get; set; }
    [NoLog]
    public string Secret { get; set; }

    public B()
    {
        this.Name = "Empty Name";
        this.CValue = new C();
    }
}

public class C
{
    public string Description { get; set; }

    public C()
    {
        this.Description = "Empty Description";           
    }
}

および NoLog カスタム属性:

public class NoLogAttribute : Attribute
{

}

あなたの質問によると、次のように sth を使用してきれいに印刷します。

public static void PrintProperties(object obj, int indent = 4, char intendCharacter = ' ')
    {
        if (obj == null) return;
        string indentString = new string(intendCharacter, indent);
        Type objType = obj.GetType();
        foreach (var pName in GetPropertiesToLogWithCaching(obj))
        {
            var property = objType.GetProperty(pName);
            object propValue = property.GetValue(obj, null);
            if (property.PropertyType.Assembly == objType.Assembly)
            {
                Console.WriteLine("{0}{1}:", indentString, property.Name);
                PrintProperties(propValue, indent + 2);
            }
            else
            {
                Console.WriteLine("{0}{1}: {2}", indentString, property.Name, propValue);
            }
        }            
    }

プロパティに (名前で) アクセスする方法を変更し、この 2 つのメソッドを追加しました。

public static List<string> GetPropertiesToLogWithCaching(object obj)
    {
        List<string> propertiesToLog = new List<string>();
        if (obj != null)
        {
            string key = obj.GetType().FullName;
            propertiesToLog = CacheLayer.Get<List<string>>(key);
            if (propertiesToLog == null)
            {
                propertiesToLog = GetPropertiesToLog(obj);
                CacheLayer.Add<List<string>>(propertiesToLog, key);
            }
        }
        return propertiesToLog;
    }

    public static List<string> GetPropertiesToLog(object obj)
    {
        List<string> propertiesToLog = new List<string>();
        if (obj != null)
        {
            foreach (var p in obj.GetType().GetProperties().Where(prop => !Attribute.IsDefined(prop, typeof(NoLogAttribute))))
            {                   
                propertiesToLog.Add(p.Name);
            }
        }
        return propertiesToLog;
    }

ここで、GetPropertiesToLogWithCaching は GetPropertiesToLog のラッパーです。ここで見つけることができる ChacheLayer オブジェクトhttp://www.deanhume.com/home/blogpost/object-caching----net-4/37

今は再帰的で、キャッシュがあります。回答の最初のバージョンで書いたように。アイデアは、プロパティ名のリストをキャッシュし、属性をテストせずに名前で GetProperty することです。キャッシュのキーとして、obj タイプの FullName を使用できます。次に、それがどのように機能するかを確認する必要があります。

于 2013-03-05T19:39:25.097 に答える