Every .net assembly contains additional metadata in addition to code. Metadata includes information about the assembly itself, such as version number, which assembly is referenced, and all types of information, including its methods, properties, and fields. Using .net reflection, this information can be read at runtime and methods can be called dynamically.
The project is almost finished, and I finally have time to write a blog,
Make an example of dynamically calling an assembly-specific method.
Project 1 (Demo) contains a Test class, and a getList method is written in the Test class. The data returned by this method is added manually. The source code is as follows:
Project 1
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
namespace Demo
{
public class Test
{
public DataTable getList(string id)
{
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("id"));
dt.Columns.Add(new DataColumn("name"));
dt.Columns.Add(new DataColumn("sex"));
DataRow dr = dt.NewRow();
dr["id"] = "zl";
dr["name"] = "Zhang Ling";
dr["sex"] = "male";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["id"] = "zl";
dr["name"] = "李思";
dr["sex"] = "female";
dt.Rows.Add(dr);
return dt;
}
}
}
Project 2 (DemoXml) contains a Test class. A getList method is written in the Test class. The data returned by this method is read from the database. The source code is as follows:
Project 2
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Xml;
namespace DemoXml
{
public class Test
{
private SqlConnection cn;
public DataTable getList(string id)
{
try
{
cn = new SqlConnection(System.Configuration.ConfigurationSettings.AppSettings["pubs"]);
SqlCommand cmd = new SqlCommand();
SqlDataAdapter da = new SqlDataAdapter();
cmd.CommandText = "SELECT au_id as id,au_lname as name,au_fname as sex from authors";
cmd.CommandType = CommandType.Text;
cmd.Connection = cn;
da.SelectCommand = cmd;
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
}
catch (Exception ex)
{
throw new ApplicationException("Exception occurred: "+ex.Message+ex.StackTrace);
}
finally
{
cn.Close();
cn = null;
}
}
}
}
Project 3 (WebDemo) demonstrates dynamically using the getList method in the specified assembly to return a DataTable, and using a gridview to display the returned data.
Call the demo
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Reflection;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
DropBind();
}
}
Data initialization, can be configured in the web.config file #region Data initialization, can be configured in the web.config file
public void DropBind()
{
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("name"));
dt.Columns.Add(new DataColumn("filepath"));
DataRow dr = dt.NewRow();
dr["name"] = "Load your own data";
dr["filepath"] = Server.MapPath(@"FilesDemo.dll");
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["name"] = "Load xml data";
dr["filepath"] = Server.MapPath(@"FilesDemoXml.dll");
dt.Rows.Add(dr);
this.DropDownList1.DataSource = dt;
this.DropDownList1.DataTextField = "name";
this.DropDownList1.DataValueField = "filepath";
this.DropDownList1.DataBind();
}
#endregion
protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
{
try
{
//Read and select the specified dll file
string strPath = (sender as DropDownList).SelectedValue.Trim();
string NameSpace = this.DropDownList1.SelectedIndex == 0 ? "Demo.Test" : "DemoXml.Test";
//Load the specified assembly into memory
Assembly assembly = Assembly.LoadFrom(strPath);
//Return a specified object in the assembly. If all objects are returned, use GetTypes() to return an array of Type objects.
Type T = assembly.GetType(NameSpace);
//Return method information (public method)
MethodInfo mi = T.GetMethod("getList");
//Create an object based on the previous type
object o = Activator.CreateInstance(T);
//parameter
object[] par = new object[] { "E01" };
//Dynamically call this method through the Invoke method of the MethodInfo object. The parameter o is because the instance method requires an instance to exist when called.
DataTable dt = (DataTable)mi.Invoke(o, par);
this.GridView1.DataSource = dt;
this.GridView1.DataBind();
}
catch (Exception ex)
{
//doException
}
}
}
The metadata in the Assembly object returned by the Assembly.LoadFrom method can be read. GetType among them will return a type object used to represent the specified assembly (reading all types in the assembly and using GetTypes will return an array of type objects).
Return method information (public method)
MethodInfo mi = T.GetMethod("getList");
Create an object based on the previous type
object o = Activator.CreateInstance(T);
parameter
object[] par = new object[] { "E01" };
This method is called dynamically through the Invoke method of the MethodInfo object. The parameter o is because the instance method requires an instance to exist when called.
DataTable dt = (DataTable)mi.Invoke(o, par);
The data returned by the call is displayed in the list.
Sample download: