Sasi
Sasi

Reputation: 27

Reading XML and executing functions dynamically using C#

I have a xml as below:

<?xml version="1.0" encoding="ISO-8859-1"?>
<TestCase Name="1.7 Bus01">
 <Action Word="Login" Text="Login" TestCaseId="MPD_QS_06">
    <Parameter Name="userName" Value="user1"/>
    <Parameter Name="userPwd" Value="user1"/>
    <Parameter Name="Tenant" Value="tnt1"/>
    <Parameter Name="expectedResult" Value="Login success"/>
 </Action>
 <Action Word="AddOrganisation" Text="AddOrganisation">
    <Parameter Name="name" Value="MAHNEWX"/>
    <Parameter Name="senderId" Value=""/>
    <Parameter Name="address" Value="77 Westferry Circus"/>
    <Parameter Name="postCode" Value="E77 4 HB"/>
    <Parameter Name="city" Value="London"/>
    <Parameter Name="country" Value="United Kingdom"/>
    <Parameter Name="state" Value=""/>
    <Parameter Name="email" Value=""/>
    <Parameter Name="telCountryCode" Value=""/>
    <Parameter Name="telNumber" Value=""/>
    <Parameter Name="telExtension" Value=""/>
    <Parameter Name="faxCountryCode" Value=""/>
    <Parameter Name="faxNumber" Value=""/>
    <Parameter Name="faxExtension" Value=""/>
    <Parameter Name="roleList" Value="MAH"/>
    <Parameter Name="expectedResult" Value="Organisation is added"/>
  </Action>
  <Action Word="NewValidationRegistration" Text="NewValidationRegistration">
    <Parameter Name="registrationname" Value="FusionUnion"/>
    <Parameter Name="AS2Identifier" Value="MPTVC"/>
    <Parameter Name="expectedResult" Value="Registration is validated"/>
  </Action>
  <Action Word="NewSubmissionRegistration" Text="NewSubmissionRegistration">
     <Parameter Name="registrationname" Value="FusionUnion"/>
     <Parameter Name="AS2Identifier" Value="MPTVC"/>
     <Parameter Name="expectedResult" Value="Registration is submitted"/>
  </Action>
  <Action Word="Logout" Text="Logout">
     <Parameter Name="expectedResult" Value="Logout success"/>
  </Action>
</TestCase> 

For each Action Word I have a method. How can I read this xml and execute the methods dynamically with parameters. The Parameter Name s are actual variables in my methods. The number of parameters differs each time. Precisely, I want to read the xml and get the list of action words and then execute them using the values. Thanks for ur help in advance.

-Sasi

Upvotes: 1

Views: 2771

Answers (2)

kmontgom
kmontgom

Reputation: 1429

I've done something broadly similar for a project I'm working on. From a high level perspective, if you can assume that the Action Word is exactly the name of a method in some assembly, then you can use reflection to get a MethodInfo corresponding to the actual function. You can then invoke the function, passing in the appropriate parameters to the method.

The one catch here is how to specify the parameters. Since there will be a variable number of parameters, you need to use a data structure which is capable of handling the variable list. I'd suggest using a Dictionary to pass the parameters.

Ok, so assuming that you can identify and load the appropriate assembly, proceed something like this:

foreach Action:

  • retrieve the value of the Word attribute into actionWordString
  • create a new Dictionary instance
  • foreach Parameter in Action:
  • retrieve the Name and Value attribute values
  • add a new entry in your Dictionary: i.e. dict[nameString] = valueString
  • use reflection to find the MethodInfo with the same name as the actionWordString and which also takes a Dictionary as a parameter
  • invoke the Method, passing in the Dictionary you previously created and populated.

It takes as much prose to describe as it does code to implement. One of the harder things, at least as I find it, is to load or access the Type of the Assembly which contains the methods. Also, it would probably be best to implement the methods as static, so that you don't have to be concerned about creating an instance of the handler class.

Upvotes: 1

L.B
L.B

Reputation: 116168

object obj = this; //your object containing methods
XDocument xDoc = XDocument.Parse(xml);
Type type = obj.GetType(); 

foreach (var action in xDoc.Descendants("Action"))
{
    MethodInfo mi = type.GetMethod(action.Attribute("Word").Value);

    var dict =  action.Descendants().ToDictionary(
                                         d=>d.Attribute("Name").Value,
                                         d=>d.Attribute("Value").Value);

    object[] parameters = mi.GetParameters()
        .Select(p => Convert.ChangeType(dict[p.Name],p.ParameterType))
        .ToArray();

    var expectedResult = mi.Invoke(obj, parameters);

    Debug.Assert(expectedResult.Equals(dict["expectedResult"]));
}

Upvotes: 3

Related Questions