There are many uses of reflection, but let's demonstrate one potential use with an example.
Suppose for example, you have a sales application installed on sales associates laptops. This application allows sales associates to enter sales orders on their laptops, when they visit the clients. The application is run in offline mode but when the sales associate returns back to the office and connects to the network, the application will detect it and automatically uploads the sales orders in a centrally hosted database.
When a sales associate enters the information, a collection of the Orders object is serialized on sales associates laptop. When this laptop is connected to the company network, the application deserializes the Orders, uses reflection to type cast the object into the Orders Type and then calls the appropriate methods to save data in the database.
Let's illustrate this with an example.
//Create an Orders Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ReflectionTest
{
public class Orders
{
private int _itemNumber;
private int _quantity;
private int _customerNumber;
//properties
public int ItemNumber
{
get { return _itemNumber; }
set { _itemNumber = value; }
}
public int Quantity
{
get { return _quantity; }
set { _quantity = value; }
}
public int CustomerNumber
{
get { return _customerNumber; }
set { _customerNumber = value; }
}
//constructor
public Orders()
{}
//Method to save data to the database
public void SaveToDB(List<Orders> orders)
{
// do something here
}
}
}
Since we are going to serialize this object and save it on associate's laptop, let's write a class that is serializable and has a variable which stores the collection of Orders object (you can make it generic to allow for serializing and storing any object).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace ReflectionTest
{
[Serializable]
public class SaveObjectLocally
{
//use generics so this class can be used to store any object types not just Orders
private List<Orders> _collObjects = new List<Orders>();
private string _saveMethod;
private string _className;
public SaveObjectLocally() { }
//properties
public List<Orders> ObjectList
{
get { return _collObjects; }
set { _collObjects = value; }
}
public string SaveToDB
{
get { return _saveMethod; }
set { _saveMethod = value; }
}
public string ClassName
{
get { return _className; }
set { _className = value; }
}
//serialize
public void Serialize(string filePath)
{
Stream stream = File.Open(filePath, FileMode.Create);
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(stream, this);
stream.Close();
}
//deserialize
public SaveObjectLocally DeSerialize(string filePath)
{
Stream stream = File.Open(filePath, FileMode.Open);
BinaryFormatter bf = new BinaryFormatter();
SaveObjectLocally SaveObject = (SaveObjectLocally)bf.Deserialize(stream);
stream.Close();
return SaveObject;
}
}
}
//Main Program
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ReflectionTest
{ class Program
{
static void Main(string[] args)
{
Orders clientOrder = new Orders();
clientOrder.ItemNumber=123;
clientOrder.Quantity = 5;
clientOrder.CustomerNumber=101;
//lets assign this order to SaveObjectLocally and
//then save it on local machine
//create a list object
List<Orders> ordersList= new List<Orders>();
ordersList.Add(clientOrder);
SaveObjectLocally save = new SaveObjectLocally();
save.SaveToDB = "SaveToDB";
save.ObjectList = ordersList;
//serialize
save.Serialize(@"C:\Temp\Orders.xml");
}
//deserialize the saved object and upload.
public static void UploadData()
{
SaveObjectLocally save = new SaveObjectLocally();
SaveObjectLocally retrieveObject = save.DeSerialize(@"C:\Temp\Orders.xml");
string saveMethod = retrieveObject.SaveToDB;
string className = retrieveObject.ClassName;
List<Orders> orders = retrieveObject.ObjectList;
//now use reflection to instantiate the object
Type ClassType = Type.GetType(className);
object obj = Activator.CreateInstance(ClassType);
System.Reflection.MethodInfo callingMethod = ClassType.GetMethod(saveMethod);
callingMethod.Invoke(obj,new Object[] {orders});
}
//If you have multiple objects serialized
//you can loop through all the files and upload one by one.
}
}
The example above is one use of Reflection where you can instantiate an object at run time and invoke its methods.
GetType.GetMethod and GetType.GetMethods() return you a single method or a list of methods.
Similarly, GetType.GetField() and GetType.GetFields() return you a single field or an array of all fields.
GetType.GetProperty() and GetType.GetProperties() returns property or a list of properties respectively.
You can also find out the parameters a method needs and also its return type. MethodInfo() provides information about the return type of a method and GetParameters() provides information about the parameters that a method expects.
GetConstructors() returns a list of constructors associated with this class.
Assembly Class
Assembly class is used to gather information about an assembly and manipulate the assembly. You can use it to load modules and assemblies at runtime and also search the type information within an assembly once it is loaded. Assembly class has the following methods
- Load() - You can pass the assembly name as input parameter to search and load the assembly.
- LoadFrom() - Takes the complete path of an assembly to search at a particular location.
- GetExecutingAssembly() - Get the information about the currently running assembly.
- GetTypes() - Allows you to obtain the details of all the types that are present in the assembly.
- GetCustomAttributes() - Gets the list of custom attributes associated with this assembly. You can also pass a Type Object as a second parameter to this method to find the attributes of a specific type associated with this assembly.
As you can imagine, reflection is a very powerful feature that allows for late binding and flexibility otherwise not available during compile time. Hopefully this article will provide you enough pointers to try out reflection on your own and discover some of its additional powerful features.
Thank you and as always, your comments are welcome.
No comments:
Post a Comment