0

我想记录每个 WCF 参数。我使用参数检查器并创建递归代码来检查所有输入中每个类中的每个属性(我的代码类似于:How to recursive print the values of an object's properties using reflection)所以我可以像这样登录文件:

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
{

}

根据你的问题,你使用这样的东西来漂亮地打印:

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

我改变了我们访问属性的方式(按名称)并为这两种方法添加了:

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

现在它是递归的并且具有缓存。正如我在答案的第一个版本中所写。我们的想法是在不测试属性的情况下按名称查询属性名称列表,而不是按名称获取属性作为缓存的键,我们可以使用 obj 类型的 FullName。现在你需要检查它是如何工作的。

于 2013-03-05T19:39:25.097 回答