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

Reflection in C#

By on in Coding

71 words, estimated reading time 1 minutes.

Introduction to Programming with C# Series
  1. Introduction to Programming with C# 7
  2. C# Programming Fundamentals
  3. Introduction to Object-Oriented Programming
  4. C# Object-Oriented Programming Part 2
  5. Flow Control and Control Structures in C#
  6. C# Data Types, Variables and Casting
  7. C# Collection Types (Array, List, Dictionary, Hash Table)
  8. C# Operators
  9. Using Data in C# 7 with ADO.Net & Entity Framework
  10. LINQ: .NET Language Integrated Query
  11. Error and Exception Handling in C#
  12. Advanced C# Programming Topics
  13. Reflection in C#
  14. What Are ASP.Net Webforms
  15. Introduction to ASP.Net MVC
  16. Windows Application Development
  17. Assemblies in C#
  18. Working with Resources Files, Culture & Regions
  19. Regular Expressions in C#
  20. Introduction to XML with C#
  21. Complete Guide to File Handling in C#

Reflection is when managed code can read its own metadata to find assemblies and modify its behaviour according to input. It does this by dynamically creating an instance of a type at runtime depending on the data it finds.

We can have a look at a few simple objects and get their type.

string test = "test";
Console.WriteLine(test.GetType().FullName);
Console.WriteLine(typeof(Int32).FullName);
Console.ReadKey();

The Type class is the foundation of Reflection. Type is a type of type Type. It serves as runtime information about an assembly, a module or a type. Every class has the function GetType which is inherited from the objecttypeof is a universal method which is used to get information about a non-instantiated type.

In this real-world example, we are going to see how we can use the name of a type (as a string) and use that to create an instance of a specific object.

There are many occasions when you need to convert a string 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.

The string can come from a number of sources, including from an XML document, database, file, configuration object.

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 dynamically 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 even a custom schema), the application needs to know what data is in what field.

In this example for a cXML document, the header contains the schema information which we will use to identify the message format.

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

I have a function that will convert this schema into a string "cXML12021".

 

We then define a base class which contains all the common properties we need to know about for the order. In this example, I'm only including a few for the sake of simplicity.

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, the class is named cXML12021 to match the schema we are going to target.

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.

This the part where we use reflection. It essentially iterates through all the types in all the loaded assemblies until it finds one that matches the schema name. When found it returns the 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!");
}

Now we can use the methods defined in the base class which are implemented using the code in the specific class in instantiated through reflection.

Last updated on: Thursday 11th October 2018

 

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.