Solving development problems  |  About this blog

Archive for the ‘reflection’ tag

Silverlight 2.0 – Invoke method with Reflection

When deciding whether to create a rich graphical web application with lots of animations either with Silverlight or ASP .NET, Silverlight definitely wins. But when deciding whether put a database in first place then server side scripts (i.e. ASP .NET) have the advantage.

Anyway, if you are accessing database from Silverlight you’ve probably came across WCF or other  web services. Let’s say you have 100 tables and want to use WCF. Each table has Select, Insert, Update and Delete methods generated like InsertUser(User item). Visual Studio 2008 can automatically generated WCF proxy classes in Silverlight which are asynchronous. Suddenly, handling application logic and database becomes complex for development.

Those methods have similarities - Select, Insert, Update and Delete are repeated but for different table names. Idea is to use System.Reflection to simply and minimize development time. What the Reflection classes do is they use run time variables (i.e. string, int, etc.) to dynamically invoke methods according to situation in run time (cannot be determined in design time while developing).

Let’s say you have a method InsertCustomer(Customer item) in WCF and Visual Studio generates InsertCustomerAsync(Customer item) for Silverlight. Application can generate “InsertCustomerAsync” as string on demand. Then a method invoke by string is needed:

using System.Reflection;

//MyWebService is WCF proxy class and Customer is data entity

MethodInfo methodInfo = typeof(MyWebService).GetMethod(“InsertCustomerAsync”, new Type[] { typeof(Customer) });

methodInfo.Invoke(con, BindingFlags.Public | BindingFlags.Instance, null, new object[] { this.item, }, null);

Then a “completed” event needs to be caught:

MethodInfo handlerInfo = typeof(ReflectionDemo<T>).GetMethod(“SaveHandler”, BindingFlags.NonPublic | BindingFlags.Instance);
EventInfo eventInfo = typeof(MyWebService).GetEvent(eventName);
eventInfo.AddEventHandler(con, Delegate.CreateDelegate(eventInfo.EventHandlerType, this, handlerInfo));

Putting all code together:

public class ReflectionDemo<T> where T : new()
{
private T item;

public bool IsUpdate
{
get;
set;
}

public void Save()
{
try
{
if (this.item != null)
{
//Get names
string methodName = (this.IsUpdate ? “Update” : “Insert”) + typeof(T).Name + “Async”; //e.g. UpdateCustomerAsync
string eventName = (this.IsUpdate ? “Update” : “Insert”) + typeof(T).Name + “Completed”; //e.g. UpdateCustomerCompleted
string eventArgsName = (this.IsUpdate ? “Update” : “Insert”) + typeof(T).Name + “CompletedEventArgs”; //e.g. UpdateCustomerCompletedEventArgs

//Create a connection
MyWebService con = new MyWebService();

//Attach an event handler in run time retrieved event (e.g. something like “con.UpdateCustomerCompleted += …” at design time)
MethodInfo handlerInfo = typeof(ReflectionDemo<T>).GetMethod(“SaveHandler”, BindingFlags.NonPublic | BindingFlags.Instance);
EventInfo eventInfo = typeof(MyWebService).GetEvent(eventName);
eventInfo.AddEventHandler(con, Delegate.CreateDelegate(eventInfo.EventHandlerType, this, handlerInfo));

//Invoke method in run time (e.g. something like “con.UpdateCustomerAsync(this.item);” at design time)
MethodInfo methodInfo = typeof(MyWebService).GetMethod(methodName, new Type[] { typeof(T) }); //From overloaded methods get the one with single parameter
methodInfo.Invoke(con, BindingFlags.Public | BindingFlags.Instance, null, new object[] { this.item, }, null); //Invoke the method immediately
}
}
catch (Exception ex)
{
//Exception may be thrown in various situations (e.g. method cannot be found)
//Insert breakpoint here while debugging
}
}

protected void SaveHandler(object sender, EventArgs args)
{

//Handle event logic here
//Sample how to cast to a derived EventArgs with known properties:

Type type = args.GetType();
Exception ex = type.GetProperty(“Error”).GetValue(args, null) as Exception ?? null;
Customer item = (Customer)type.GetProperty(“Customer”).GetValue(args, null);
}

Written by Avivo

July 3rd, 2009 at 2:45 pm