Learning never exhausts the mind
Home >  Coding > C# ASP.Net MVC > Converting a String Name into a C# Type

Last Updated on by

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

Leave a Reply

Fields marked with * are mandatory.

We respect your privacy, and will not make your email public. Hashed email address may be checked against Gravatar service to retrieve avatars. This site uses Akismet to reduce spam. Learn how your comment data is processed.