Introduction

Sometimes, we need to config our application using a config file such as XML. We have to parse the whole XML document to pick up the right value with dozens of 'if'. Now, we can use reflection technology to set values with lesser 'if' by enumerating the XML document and set the right value.

Getting Started

In the following example, we'll have an config.xml definition, something like this:

<Student>
    <ID>001</ID>
    <Name>Foo</Name>
    <Sex>Unsexed</Sex>
</Student>

Using the Code

We had a class 'Student' in our application:

class Student
{
    /// <summary>
    /// The student's name
    /// </summary>
    public string Name { get; set; }
    /// <summary>
    /// The student's id
    /// </summary>
    public int ID { get; set; }
    /// <summary>
    /// The student's sex
    /// </summary>
    public string Sex { get; set; }
}

First, we set their values one by one, using XPath:

static Student SetStudentInfoFromXml(string xmlConfigFile)
{
    Student theStudent = new Student();
    /******define lots of xmlpath*****
    *we can imagine if we had lot of properties to set,
    *we'll need to define them all !
    */
    string idPath = "/Student/ID";
    string namePath = "/Student/Name";
    string sexPath = "/Student/Sex";

    XmlDocument studentInfoDoc = new XmlDocument();
    studentInfoDoc.Load(xmlConfigFile);
    //load an student's config file for parse

    //here, we have to write mass of "duplicated" code.
    var id = studentInfoDoc.SelectSingleNode(idPath).InnerText;
    var name = studentInfoDoc.SelectSingleNode(namePath).InnerText;
    var sex = studentInfoDoc.SelectSingleNode(sexPath).InnerText;

    //then give them a proper value
    theStudent.ID = int.Parse(id);
    theStudent.Name = name;
    theStudent.Sex = sex;

    //object creating completed
    return theStudent;
}

As we can see in the code above, we did mass unnecessary operations, so we can use reflection instead.

/// <summary>
/// set information for specified student using reflection
/// </summary>
/// <param name="xmlConfigFile">student's xml configuration file
/// <returns>an student object with properties set</returns>
static Student SetStudentInfoFromXmlByReflection(string xmlConfigFile)
{
    Student theStudent = new Student();
    XmlDocument studentInfoDoc = new XmlDocument();
    studentInfoDoc.Load(xmlConfigFile);
    XmlNodeList stuConfigItems = studentInfoDoc.SelectSingleNode("/Student").ChildNodes;
    //load an student's config file for parse

    //enumerate the xml document
    foreach (XmlNode stuConfigItem in stuConfigItems)
    {
        try
        {
            //first, we need to get an property object(instance) of the student
            var studentPropObj = theStudent.GetType().GetProperty(stuConfigItem.Name);
            //and try to convert to the right value type
            object value = Convert.ChangeType
		(stuConfigItem.InnerText, studentPropObj.PropertyType);
            //finally we set its value
            studentPropObj.SetValue(theStudent, value, null);
        }
        catch
        {
            Console.WriteLine("Error while setting value!");
        }
    }

    return theStudent;
}

Then, we do less work for the same goal. The program has the following output:

The output for this program
推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架
新浪微博粉丝精灵,刷粉丝、刷评论、刷转发、企业商家微博营销必备工具"