Sony Arouje

a programmer's log

Posts Tagged ‘ToStringHelper

ToStringHelper

leave a comment »

The implementation is inspired by Google Guava libraries. ToStringHelper is a simple class helps to get all the property values of a class in string format. Some times for logging purpose we may need the property values of entities, to achieve that we override ToString()  and append the required property values. ToStringHelper will ease this step.

In Guava libs, ToStringHelper is implemented as fluent APIs and user needs to provide the property and values as shown below.

return InstanceHelper.ToStringHelper(this).Add("Name", Name).Add("Age", Age).ToString();

 

I am very lazy of doing this way, so I used reflection to do my job. In the later part of this post you can see the implementation of ToStringHelper and how I get the value using reflection.

Let’s see the use of this helper method.

public class Student
{
    public Student(string name,string lastName, int age)
    {
        this.Name = name;
        this.Age = age;
        this.LastName = lastName;
    }
    [UseInToString(AliasName="Student Name")]
    public string Name { get; private set; }

    [UseInToString]
    public int Age { get; private set; }

    public string LastName { get; private set; }
    public override string ToString()
    {
        ToStringHelper toStrngHelper = new ToStringHelper("Student");
        toStrngHelper.Add<Student>(this);
        return toStrngHelper.ToString();
    }
}

Have a look at the above class. I override ToString() and called the ToStringHelper to provide a textual data. This way I can avoid all the repeated process of appending and returning the values from ToString function. In my scenario I don’t need all the value in the string returned by ToString. So I created a CustomAttribute called UseInToString, which ever the property decorated with UseInToString will be used in creating the string output. Also we can provide an AliasName for the property, if AliasName exist then AliasName will be used instead of Property name.

Let’s write a test and see whether out function works fine.

[TestCase]
public void TestInstanceHelper()
{
    Student student = new Student("Sony","Arouje",30);
    Assert.AreEqual("Student{Student Name: Sony, Age: 30}", student.ToString());
    Console.WriteLine(student.ToString());
}

No more description required for the above test case, the output is pretty much self explanatory.

Now let’s have a look at the ToStringHelper class and UseInToString custom attribute

[System.AttributeUsage(System.AttributeTargets.Property)]
public class UseInToString : System.Attribute
{
    private string _humanReadablePropertyName;
    public string AliasName 
    {
        get { return _humanReadablePropertyName; }
        set { _humanReadablePropertyName = value; }
    }
}

public class ToStringHelper
{
    StringBuilder _outPutValue = null;
    string _delimiter = string.Empty;
    public ToStringHelper(object instance)
    {
        _outPutValue = new StringBuilder
        (instance.GetType()==typeof(string)?instance.ToString():instance.GetType().Name);
        _outPutValue.Append("{");
    }
    private void Add(string name, object value)
    {
        _outPutValue.Append(string.Format("{0}{1}: {2}", _delimiter, name, value));
        _delimiter = ", ";
    }
    public override string ToString()
    {
        _outPutValue.Append("}");
        return _outPutValue.ToString();
    }

    public void Add<TClazz>(TClazz clazz) where TClazz : class
    {
        object propertyValue;
        typeof(TClazz).GetProperties().Where(pr => pr.CanRead).ToList()
        .ForEach(property =>
        {
            UseInToString useInAttr = (UseInToString)property.GetCustomAttributes(false)
                                           .FirstOrDefault(attr => attr is UseInToString);
            if (useInAttr != null)
            {
                propertyValue = property.GetValue(clazz, null);
                this.Add(string.IsNullOrEmpty(useInAttr.AliasName) ? property.Name 
                                              : useInAttr.AliasName, propertyValue);
            }
        });
        
    }
}

I think the class describes what it does. Hope you may find it useful. Happy coding…

Written by Sony Arouje

September 24, 2011 at 2:50 am

Posted in .NET

Tagged with , ,

%d bloggers like this: