Reflection with Example

Introduction

Process of runtime type discovery is called reflection. Using reflection we are able to obtain the metadata information, dynamically. For example we can get list of all types contained within a given assembly, including methods, attributes, fields, custom attributes, properties and many more.

System.Type

Before dive into reflection, first have a look at System.Type class. Because it is a base foundation of reflection api.

System.Type class defiens many members that can be used to explore a type’s metadata information. Many of its member return type is from System.Reflection namespace. For example, GetProperties() returns a PropertyInfo[], GetFields() returns FieldInfo[] and so on.

System.Type contains property like: IsAbstarct, IsArray, IsClass, IsCOMObject, IsValueType, IsInterface, IsPrimitive, IsEnum and list goes on, which allow to find basics features about the Type in context, for example if it is a abstract class, an array and so on.

It also contains method like GetMethods(), GetProperties(), GetNestedTypes(), GetInterfaces(), GetEvents(), GetConstructors(), etc., allow to get an array representing the items(methods, property, interfaces, etc.) we are exploring.

Notes: Each of these method has a singular form, for example, GetMethod(),GetProperty(), etc., that allows to get a specific item by name.

System.Reflection

This namespace contains types that retrieve information about assemblies, modules, members, parameters and other entity. These also can be used to manipulate instance of loaded types, for example invoking methods etc.

Brief Discription of some member of System.Reflection namespace:

  • Assembly: An abstract class that contains many static methods that allow to load, investigate and manipulate an assembly.
  • AssemblyName: This class allows to discover more details for an assembly for e.g. version Info, culture info etc.
  • EventInfo: An abstract class holds information for a given event.
  • FieldInfo: An abstract class holds information for a given field.
  • MemberInfo: This abstract class that defines common behavior for the EventInfo, FiedInfo, MethodInfo and PropertyTypeInfo.
  • MethodInfo: An abstract class holds information for a given method.
  • Module: An abstract class that allow to access a given module within a multifile assembly.
  • ParameterInfo: An abstract class holds information for a given parameter.
  • PropertyInfo: An abstract class holds information for a given property.

Get Type Reference

We can get an instance of Type class in various of ways.

Using System.Object.GetType()

System.Object defines a method named GetType(), which returns an instance of the Type class that represents the metadata for the current object.

This approach will work only if we have compile-time knowledge of the type which we want to explore and currently have an instance of the type in memory.

Using typeof()

The other way is to obtain type metadata is using the typeof operator:

This approach don’t require to create an object instance to type information.

Using System.Type.GetType()

Type.GetType() provide type information in more flexible manner. Using this method we do not need to have compile time knowledge of the type, since we specify the fully qualified string name of the type that is to be explore.

The Type.GetType() method has been overloaded to specify two Boolean parameters, one of which controls whether an exception should be thrown if the type cannot be found, and the other of which check the case sensitivity of the string.

In this code, the assumption is that the type is defined within the currently executing assembly. However, when we want to obtain metadata for a type within an external assembly, the string parameter is formatted using the type’s fully qualified name, followed by a comma, followed by the friendly name of the assembly containing the type:

In Type.GetType() method we can also specify a plus token (+) to denote a nested type. Suppose we want to get type information for a class (ClassName) which is nested within a class named {Class_Name}.

Getting Methods Information

In this method, a parameter is passed of type Type. From this type, to get all method GetMethod() is called that return an array of MethodInfo instance. Now iterating through all methodInfo, we can get return type of that method using methodInfo.ReturnType.FullName. Now to get all parameters of that method we call methodInfo.GetParameters(). From parameterInfo we get parameter type and its name.

Getting Field information


To get all fields, I am using GetFields() that retrun a FieldInfo[] object, and from fieldInfo object we can get its information.

In this method I am using BindingFlags(which is an enum) that control binding and the way in which the exploring for members and types is used by reflection. This provides a greater level of control on exactly what we are searching for (e.g., only static members, only public members, include private members, etc.).

Some Binding flags are:

  • BindingFlags.Public: Specifies that public members are to be included in the search.
  • BindingFlags.Instance: Specifies that instance members are to be included in the search.
  • BindingFlags.NonPublic: Specifies that non-public members are to be included in the search.

Getting Property information

Getting some various Statistics

Last but not least, you have one final helper method that will simply display various statistics (indicating whether the type is generic, what the base class is, whether the type is sealed, and so forth) regarding the incoming type.

Example Application

Example Application is web application to provide use of reflection by creating instance at run time, basic database operation (CRUD operation and creation of stored procedure) etc.

So the idea is perform Crud operation which requires to have stored procedure in database, and passing sql parameter when calling the stored procedure. To demonstrate reflection in C# application, I am doing all operation through reflection api like creating instance of repository, creating stored procedure, creating SqlParameter, converting DataTable to List etc.

Firstly I created custom attributes for class property that represent my database table, to identify Identity column and general column and to mapping class to table.

I use this attribute for mapping table name to class.

This attribute is apply on class property, to represent that this property is identity column in database.

This attribute is used in to represent corresponding column name in table.

This is how I used these attribute in my model class:

Getting List of SqlParameter

In this method, an instance of object in received whose have to get the SqlParameter to pass the stored procedure. Firstly I get the all public and non-static property and iterating through all property info I add it to SqlParameter list.

Get Table Name

Getting table to use in procedure for an object I created this extension method

To Create Stored Procedure

I have created stored procedure for database operation, by calling


I created CreateParameter method for programmatically create a stored procedure for entity. In this method, object for whose we want to create procedure should be decorated with attribute like, TableNameAttribute, etc. for getting table name, and getting column name and its types.


Saving data to database

This is how I calling my repository instance to save the data from aspx page. In this method Activator.CreateInstance() is used to create an instance of the specified type.

Convert Table to List<T>

In this extension method what I am doing is to covert datatable to its representing list of object by matching datatable header with class attributes. This code is actually taken from this article, with some modification.


Performance and Reflection

Reflection come up with the cost. But that cost depends on the implementation (repetitive calls should be cached for example: entity.GetType().GetProperty(BindingFlag.Public)).

For example in this article code example there are methods GetAddParameter, GetUpdateParameter. In these two methods I have called obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance) each time method is called. For example, if I have a million Widgets and I call your GetAddParameter method for each of them, it would call GetType and GetProperties a million times and each time it will return exactly the same information as all the other times. This is exceedingly wasteful. So for this senario Mr. PIEBALDconsult Suggested that this method should be cached. So I came up with this final version of GetAddParameter and GetUpdateParameter.




Some Useful links:

Reflection is neither bad, nor slow. It is simply a tool. Like all tools, it is very valuable for certain scenarios, not so valuable for others.

Last Words

What I learned during this example is the main value of Reflection, such as it can be used to inspect assemblies, types, and members. It’s a very powerful tool for determining the contents of an unknown assembly or object and can be used in a wide variety of cases.



I hope that you will have better understanding of Reflection. I would like to hear valuable feedback or question from you. It encourage me to write more quality article.
Happy Reading 🙂

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s