LateBinding

by ion.robu 10. February 2009 16:55

In this article we will present a sample about how to use late binding in .NET using System.Reflection namespace and System.Type class.

What is Late Binding? – is a mechanism which allow to instantiate types and accessing members of objects created without knowing these types at compile time. Shortly, these types are not referred “classically”, through dot and new operators, but at runtime, acquiring information about structure type, instantiating objects and invoking its members. All of these without referring that type at all (anyway, we cannot do that, given that we did not include information about that type at compiling time.). All we need is to know structure of used type, more exactly, knowing what methods and properties we need to use.

This approach can be very useful in a lot of cases, due of these capabilities to manipulate objects at runtime, while they are unknown at compile time; this fact help us to provide a much more flexibility to our applications when interacting with others application and/or third-party software (such as COM).

Example – in the following example, we will manipulate objects from a .NET assembly using reflection mechanisms. In this assembly we have class Employee, which exposes some members and methods, and class EmployeeMethods, which exposes a collection of Employee objects and some methods which works on this collection. These 2 types (classes) will be used from main application (a website) without referring it at developing type, but operating on it at execution time. The referred assembly is stored on disk, and its location is given in web.config (you should copy it manually in this location).

Here is the code:

Code from assembly Objects.LateBinding.dll

using System;

using System.Collections.Generic;

namespace Objects.LateBinding

{

       public class Employee

       {

              public string EmployeeName = "";

              public int EmployeeAge = 0;

              public string EmployeeFunction = "";

              public Employee(string name, int age, string function)

              {

                     EmployeeName = name;

                     EmployeeAge = age;

                     EmployeeFunction = function;

              }

              public string PresentEmployee()

              {

                     return string.Format("Hi, I am {0}, {1} years old and I work as {2}", EmployeeName,EmployeeAge, EmployeeFunction);

              }

       }

       public class EmployeeMethods

       {

              public List<Employee> Employees;

              public void Init()

              {

                     //in real scenarios, data will be loaded from various sources

                     Employees = new List<Employee>();

                     Employees.Add(new Employee("John", 26, "Programmer"));

                     Employees.Add(new Employee("Joe", 30, "Web developer"));

                     Employees.Add(new Employee("Jim", 40, "Software architect"));

              }

              public Employee GetEmployee(int i)

              {

                     return Employees[i];

              }

              public int GetEmployeesCount()

              {

                     return Employees.Count;

              }

              public void AddEmployee(string name, int age, string function)

              {

                     Employees.Add(new Employee(name, age, function));

              }

       }

}

Code from Default.aspx.cs from main application:

using System;

using System.Data;

using System.Configuration;

using System.Web;

using System.Reflection;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

public partial class _Default : System.Web.UI.Page

{

       Assembly Asmb = null;

       Type EmployeeMethods = null;

       Type EmployeeType = null;

       object EmpMethods = null;

    protected void Page_Load(object sender, EventArgs e)

    {

              InitTypes();

              if (!IsPostBack)

              {

                     InitEmployees();

                     PresentEmployees();

              }

    }

       private void InitTypes()

       {

              //get assembly with Employee classes

              Asmb = Assembly.LoadFrom(System.Configuration.ConfigurationManager.AppSettings["TestAssembly"]);

              //get EmployeeMethods type information

              EmployeeMethods = Asmb.GetType("Objects.LateBinding.EmployeeMethods");

              EmpMethods = Activator.CreateInstance(EmployeeMethods);

       }

       private void InitEmployees()

       {

              //invoke Init method on EmployeeMethods to init employee collection

              MethodInfo mtdInfo = EmployeeMethods.GetMethod("Init");

              mtdInfo.Invoke(EmpMethods, null);

       }

       private void PresentEmployees()

       {

              //get employees count from EmployeeMethods object created earlier

              MethodInfo mtdInfoEmpCount = EmployeeMethods.GetMethod("GetEmployeesCount");

              object employeesCount = mtdInfoEmpCount.Invoke(EmpMethods, null);

              int emplCount = (int)employeesCount;

              //get each employee object

              for (int i = 0; i < emplCount; i++ )

              {

                     object[] parEmpl = new object[] { i };

                     MethodInfo mtdInfoEmp = EmployeeMethods.GetMethod("GetEmployee");

                     object employee = mtdInfoEmp.Invoke(EmpMethods, parEmpl);//get employee

                     //invoke PresentEmployee method for current employee

                     EmployeeType = employee.GetType();

                     MethodInfo mtdInfoEmpPresent = EmployeeType.GetMethod("PresentEmployee");

                     object employeePresent = mtdInfoEmpPresent.Invoke(employee, null);

                     //display the 'response' of the method

                     Response.Write(employeePresent.ToString() + "<br/>");

              }

       }

       private void AddEmployee(string Name, int Age, string Function)

       {

              //Add employee with values from interface

              object[] parEmpl = new object[] { Name, Age, Function };

              MethodInfo mtdInfoEmpAdd = EmployeeMethods.GetMethod("AddEmployee");

              mtdInfoEmpAdd.Invoke(EmpMethods, parEmpl);

       }

       protected void btnAddEmployee_Click(object sender, EventArgs e)

       {

              InitEmployees();

              AddEmployee(txtName.Text, int.Parse(txtAge.Text), txtFunction.Text);

              PresentEmployees();

       }

}

Code from Default.aspx:

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

    <title>Late binding</title>

</head>

<body>

    <form id="form1" runat="server">

    <div>

              <table>

                     <tr>

                           <td colspan="2"><b>Add an employee:</b></td>

                     </tr>

                     <tr>

                           <td>Name:</td>

                           <td><asp:TextBox ID="txtName" runat="server"></asp:TextBox></td>

                     </tr>

                     <tr>

                           <td>Age:</td>

                           <td><asp:TextBox ID="txtAge" runat="server"></asp:TextBox></td>

                     </tr>

                     <tr>

                           <td>Function:</td>

                           <td><asp:TextBox ID="txtFunction" runat="server"></asp:TextBox></td>

                     </tr>

                     <tr>

                           <td colspan="2"><asp:Button ID="btnAddEmployee" runat="server" OnClick="btnAddEmployee_Click" Text="Add employee"/></td>

                     </tr>

              </table>

    </div>

    </form>

</body>

</html>

In this example we list some employees, hardcoded, and add a new one through web interface, using only reflection mechanisms.

Note: Code is not optimized, and no validation was made, since is not point of interest in this article.

Prj.rar (7.70 kb)

Tags:

Programming

Comments

Comments are closed

Powered by BlogEngine.NET 1.5.0.7
Theme by Mads Kristensen

RecentComments

Comment RSS

Calendar

<<  February 2012  >>
MoTuWeThFrSaSu
303112345
6789101112
13141516171819
20212223242526
2728291234
567891011

View posts in large calendar