Каждая сборка .net помимо кода содержит дополнительные метаданные. Метаданные включают информацию о самой сборке, например номер версии, на какую сборку ссылаются, а также все типы информации, включая ее методы, свойства и поля. Используя отражение .net, эту информацию можно читать во время выполнения, а методы можно вызывать динамически.
Проект почти завершен, и у меня наконец-то появилось время написать блог.
Приведите пример динамического вызова метода, специфичного для сборки.
Проект 1 (демо) содержит класс Test, а в классе Test написан метод getList. Данные, возвращаемые этим методом, добавляются вручную. Исходный код выглядит следующим образом:
Проект 1
использование системы;
использование System.Collections.Generic;
использование System.Text;
использование
пространства имен System.Data Demo
;
{
тест публичного класса
{
общедоступный DataTable getList (идентификатор строки)
{
DataTable dt = новый DataTable();
dt.Columns.Add(новый DataColumn("id"));
dt.Columns.Add(новый DataColumn("имя"));
dt.Columns.Add(новый DataColumn("секс"));
DataRow dr = dt.NewRow();
dr["id"] = "зл";
dr["name"] = "Чжан Лин";
dr["секс"] = "мужской";
dt.Rows.Add(др);
др = dt.NewRow();
dr["id"] = "зл";
dr["name"] = "李思";
dr["секс"] = "женщина";
dt.Rows.Add(др);
вернуть DT;
}
}
}
Проект 2 (DemoXml) содержит класс Test. В классе Test написан метод getList. Данные, возвращаемые этим методом, считываются из базы данных. Исходный код выглядит следующим образом:
Проект 2
использование системы;
использование System.Collections.Generic;
использование System.Text;
использование System.Data;
использование System.Data.SqlClient;
использование System.Xml;
пространство имен DemoXml
{
тест публичного класса
{
частный SqlConnection cn;
общедоступный DataTable getList (идентификатор строки)
{
пытаться
{
cn = новый SqlConnection(System.Configuration.ConfigurationSettings.AppSettings["pubs"]);
SqlCommand cmd = новый SqlCommand();
SqlDataAdapter da = новый SqlDataAdapter();
cmd.CommandText = "ВЫБЕРИТЕ au_id в качестве идентификатора, au_lname в качестве имени, au_fname в качестве пола от авторов";
cmd.ТипКоманды = ТипКоманды.Текст;
cmd.Connection = сп;
da.SelectCommand = cmd;
DataTable dt = новый DataTable();
да.Заполнить(дт);
вернуть DT;
}
поймать (Исключение ex)
{
throw new ApplicationException("Произошло исключение: "+ex.Message+ex.StackTrace);
}
окончательно
{
сп.Закрыть();
сп = ноль;
}
}
}
}
Проект 3 (WebDemo) демонстрирует динамическое использование метода getList в указанной сборке для возврата DataTable и использование GridView для отображения возвращенных данных.
Вызов демо-версии
использование системы;
использование System.Data;
использование System.Configuration;
использование System.Web;
использование System.Web.Security;
использование System.Web.UI;
использование System.Web.UI.WebControls;
использование System.Web.UI.WebControls.WebParts;
использование System.Web.UI.HtmlControls;
общедоступного частичного класса
System.Reflection
_Default: System.Web.UI.Page;
{
protected void Page_Load (отправитель объекта, EventArgs e)
{
если (!IsPostBack)
{
ДропБинд();
}
}
Инициализация данных, можно настроить в файле web.config #region Инициализация данных, можно настроить в файле web.config
публичная недействительность DropBind()
{
DataTable dt = новый DataTable();
dt.Columns.Add(новый DataColumn("имя"));
dt.Columns.Add(новый DataColumn("путь к файлу"));
DataRow dr = dt.NewRow();
dr["name"] = "Загрузить свои данные";
dr["filepath"] = Server.MapPath(@"FilesDemo.dll");
dt.Rows.Add(др);
др = dt.NewRow();
dr["name"] = "Загрузить данные XML";
dr["filepath"] = Server.MapPath(@"FilesDemoXml.dll");
dt.Rows.Add(др);
this.DropDownList1.DataSource = dt;
this.DropDownList1.DataTextField = "имя";
this.DropDownList1.DataValueField = "путь к файлу";
это.DropDownList1.DataBind();
}
#endregion
protected void DropDownList1_SelectedIndexChanged (отправитель объекта, EventArgs e)
{
пытаться
{
//Читаем и выбираем указанный файл dll
строка strPath = (отправитель как DropDownList).SelectedValue.Trim();
строка NameSpace = this.DropDownList1.SelectedIndex == 0 «Demo.Test»: «DemoXml.Test»;
//Загружаем указанную сборку в память
Сборка сборки = Assembly.LoadFrom(strPath);
//Возвращаем указанный объект в сборке. Если возвращены все объекты, используйте GetTypes() для возврата массива объектов Type.
Тип T = сборка.GetType(NameSpace);
// Возвращаем информацию о методе (публичный метод)
MethodInfo mi = T.GetMethod("getList");
//Создаем объект на основе предыдущего типа
объект o = Activator.CreateInstance(T);
//параметр
объект [] пар = новый объект [] { "E01" };
//Динамически вызывать этот метод через метод Invoke объекта MethodInfo. Параметр o нужен потому, что метод экземпляра требует существования экземпляра при вызове.
DataTable dt = (DataTable)mi.Invoke(o, par);
this.GridView1.DataSource = dt;
это.GridView1.DataBind();
}
поймать (Исключение ex)
{
//делать исключение
}
}
}
Метаданные в объекте Assembly, возвращаемые методом Assembly.LoadFrom, можно прочитать. Среди них GetType вернет объект типа, используемый для представления указанной сборки (чтение всех типов в сборке и использование GetTypes вернет массив объектов типа).
Информация о методе возврата (открытый метод)
MethodInfo mi = T.GetMethod("getList");
Создать объект на основе предыдущего типа
объект o = Activator.CreateInstance(T);
параметр
объект [] пар = новый объект [] { "E01" };
Этот метод вызывается динамически через метод Invoke объекта MethodInfo. Параметр o обусловлен тем, что метод экземпляра требует существования экземпляра при вызове.
DataTable dt = (DataTable)mi.Invoke(o, par);
Данные, возвращаемые вызовом, отображаются в списке.
Пример загрузки: