0

I would like to log to file every WCF parameters. I use parameter inspector and create recursive code for inspecting every property in every class in all inputs (my code is similar to: How to recursively print the values of an object's properties using reflection) so I can log in file like:

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

Unfortunately I have to change my code to do not log properties which are marked with custom attribute called NoLog. I modified my code to get attributes of every property but because every time I'm inspect parameters my code really slow down.

So my question is: how can I provide caching?

6
  • 2
    Your logging requirements are so special that the built-in wcf logging is no good? Commented Mar 5, 2013 at 19:30
  • Are you able to reach, and/or install, an AppFabric Caching server? Commented Mar 5, 2013 at 19:34
  • @rene this attribute for example means that wcf logging is wrong in this case Commented Mar 5, 2013 at 20:03
  • @Michael AppFabric has no use here Commented Mar 5, 2013 at 20:05
  • @Garath, I guess you already have a solution in mind then huh? Commented Mar 5, 2013 at 20:37

1 Answer 1

4

There are some classes:

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

and NoLog custom attribue:

public class NoLogAttribute : Attribute
{

}

According to your question you use sth like this to pretty print:

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

I changed the way how we access properties (by name) and added for this two methods:

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

where GetPropertiesToLogWithCaching is wrapper of GetPropertiesToLog. ChacheLayer object you can find here http://www.deanhume.com/home/blogpost/object-caching----net-4/37

Now it is recursive and it has caching. As I wrote in first version of answer. The idea is to chache list of properties names and than GetProperty by name without testing attributes as a key for cache we can use FullName of obj Type. Now you need to check how it works.

Sign up to request clarification or add additional context in comments.

1 Comment

I changed this a bit, but it is ok

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.