Web Design that taps into the haromny and vision of your dreams.

Converting a String Name into a C# Type

Using reflection to convert a string name to an instance of a class

By on in Coding

474 words, estimated reading time 3 minutes.

There are many occasions when you need to convert a string (from an XML document, database, file and so on) into an instance of a class. For example when you need to create an instance of a class, but the exact type is unknown. This example will show you how to get a type from a string and use reflection to create an instance of it.

This example is going to be loosely based on a Punchout system, where a customer will send an XML document to the web service. The XML document can be of any number of types (the most common being cXML) and the application needs to know how to handle it.

When the web service is invoked, it is passed an XML document which contains a number of elements to identify the sender and authenticate. Since the XML document can be of any number of standards (or custom), the application needs to know what data is in what field. So far I have been using a tag in the XML to identify the standard used.

<!DOCTYPE cXML SYSTEM "http://xml.cXML.org/schemas/cXML/1.2.021/cXML.dtd">

I have a function that will convert this into cXML12021.

public class PunchoutBaseClass
{
  public abstract string CustomerName;
  public abstract string DeploymentMode;
  public abstract string SelectedService;
}

After this, you will need some classes that will implement this class. They should be named in such a way that the class name can be obtained from the source. In this example, cXML12021.

Note: You will need to code the actual implementation; the code below is only given as an example.

public class cXML12021 : PunchoutBaseClass
{
  public override string CustomerName
  {
    get { return XmlDocument.SelectSingleNode("/cXML/Sender/Credential/Identity").InnerText; }
  }
  public override string DeploymentMode
  {
    get { return XmlDocument.SelectSingleNode("/cXML/Request/@deploymentMode").InnerText; }
  }
  public override string SelectedService
  {
    get { return XmlDocument.SelectSingleNode("/cXML/Request/ProviderSetupRequest/SelectedService").InnerText; }
  }
}
 
public class uniqCustFormat : PunchoutBaseClass
{
  public override string CustomerName
  {
    get { return XmlDocument.SelectSingleNode("/Setup/UserID").InnerText; }
  }
  public override string DeploymentMode
  {
    get { return XmlDocument.SelectSingleNode("/Setup/Mode").InnerText; }
  }
  public override string SelectedService
  {
    get { return XmlDocument.SelectSingleNode("/Setup/RequestType").InnerText; }
  }
}
 

You should be able to see that although the two classes expose the same properties to the developer, the actual implementation is different.

Now we know what class to instantiate, and we have two classes that inherit from the base class we can use a short snippet to get the .Net assembly type.

public static Type StringToType(string typeName)
{
    foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
    {
        Type foundType = assembly.GetType(typeName);
 
        if (foundType != null)
            return foundType;
    }
    return null;
}

Usage is simply a case of passing in a string containing cXML12021.

string XmlType = "cXML12021"; // This can be generated dynamically
Type t = StringToType(XmlType);

Now, all we need to do is use the powerful reflection classes to create an instance of the cXML12021 class. This can only be done because we are using a base class. We actually create an instance of the base class which takes the form of the cXML12021 class.

if (t != null)
{
  PunchoutBaseClass cXml = (PunchoutBaseClass)Activator.CreateInstance(t);
  Response.Write(cXml.CustomerName);
}
else
{
  Response.Write("Class name not found!");
}

Last updated on: Wednesday 21st June 2017

 

Comments

Have a question or suggestion? Please leave a comment to start the discussion.

 

Leave a Reply

Please keep in mind that all comments are moderated according to our privacy policy, and all links are nofollow. Do NOT use keywords in the name field. Let's have a personal and meaningful conversation.

Your email address will not be published.