Сборки. Статическое и динамическое связывание сборок. Класс сборки Assembly.
Библиотеки в .Net Framework называются сборкой (assembly) – набор функций скомпилированный в IL – код (промежуточный язык). В отличие от обычных dll–библиотек сборки обладают возможностью контроля версий, региональной культуры и защиты от несанкционированного изменения. Приложение может использовать сборки с уточнением любого из этих параметров. 1) Сборки определяют границы безопасности, т.е. можно установить для каждой сборки такую политику безопасности кода, которая будет уникальна в пределах сборки. 2) Сборки разграничивают типы, т.е. любой тип данных имеет неявную подпись в сборке, где он содержится. 3) Сборки обеспечивают контроль версий. 4) Сборки обеспечивают технологию прямого запуска. В одном адресном пространстве могут находиться 2 одинаковые сборки различных версий. 5) Сборки обеспечивают удаленную загрузку кода приложения.
Одна сборка может состоять из нескольких модулей. Модули могут располагаться на удаленных источниках и загружаться по мере необходимости. Один и тот же модуль может входить в несколько сборок. Для хранения сборок существует 2 стратегии: 1. Можно ее положить в той же папке, где находится само приложение. 2. Её можно инсталлировать в GAC (Global Assembly Cache – глобальное хранилище сборок). GAC представляет собой папку. Расположена она по адресу: %Windows%\ Assembly. В GAC могут располагаться только подписочные сборки.
Создание строго именованных сборок.1) sn-k <имя файла> .snk — создает пару: открытый-закрытый ключ. 2) sn-tp <имя файла>.snk — открытый ключ и его маркер. 3) В AssemblyInfo.cs надо поменять или указать следующий атрибут: [assembly: AssemblyKeyFile (<>.snk)]
После выполнения всех действий сборку можно отдавать в свободное пользование.
Статические сборки существуют в виде файлов на жестком диске или других носителях. В отличие от них динамические сборки создаются в оперативной памяти «налету», прямо в процессе выполнения программы. Для этого используются типы, определенные в пространстве имен System. Reflection.Emit. После того как мы создали сборку вместе с модулями и находящимися в ней типами, мы можем сохранить ее (в процессе выполнения программы) на жестком диске. В результате будет создана новая статическая сборка. Кроме того, при помощи типов из System.Reflection.Emit вполне возможно добавлять новые типы и члены в представление уже загруженной в оперативную память сборки. Обычно при использовании типов из System.Reflection значительную часть работы выполняет класс Assembly. При помощи этого класса мы можем динамически загружать сборки, обращаться к членам класса в процессе выполнения (позднее связывание), а также получать информацию о самой сборке. Для загрузки сборки используется статический метод Assembly.Load(), которому передается текстовое имя. Чтобы получить информацию об имени каждого типа, определенного в сборке используется метод Assembly.GetTypes().
14. Позднее связывание. Класс System.Activator. Создание экземпляра объекта путем позднего связывания. Вызов методов объекта путем позднего связывания.
Позднее связывание (latebinding) — это технология, которая позволяет обнаруживать типы, определять их имена и члены непосредственно в процессе выполнения (в отличие от обычного раннего связывания, когда эти операции производятся во время компиляции). Такую возможность предоставляет пространство имен System.Reflection. После того как наличие типа установлено, мы можем динамически вызывать его методы, получать доступ к свойствам, устанавливать значения полей и т. п. Как правило, позднее связывание используется в достаточно сложных программах. Раннее связывание обеспечивает обнаружение возможных ошибок еще во время выполнения, и, как правило, его применение более надежно. Позднее связывание часто используется при создании средств разработки, а также для взаимодействия COM/.NET.
Главный тип, при помощи которого в .NET реализуется позднее связывание, — это класс System.Activator. В нем помимо методов, унаследованных от System.Object, содержится лишь несколько собственных членов. Самый важный из них — это метод Activator.CreateInstance(). Этот метод предназначен для создания объекта типа во время выполнения. Существует несколько перегруженных вариантов этого метода, обеспечивающих большую гибкость в использовании. Вариант CreateInstance() принимает готовый объект типа Туре:
/ / Создаем объект выбранного нами типа
public class Class1{
public static int Main(string[] args){
// Используем класс Assembly для загрузки сборки
Assembly a = null:
try
{а = Assembly. Load(“CarLibrary");}
catch(FileNotFoundException e)
{Console.WriteLine(e.Message);}
/ / Получаем объект Type для класса MiniVan
Type miniVan = a.GetType(“CarLibrary.MiniVan");
// Создаем объект класса MiniVan "на лету"
object obj = Activator.CreateInstance(miniVan};
}
}
obj указывает на объект класса MiniVan, который был создан при помощи метода Activator.CreateInstance. Чтобы вызвать метод TurboBoost() для этого объекта нужно получить объект класса MethodInfo при помощи Type.GetMethod(). Затем можно использовать этот объект MethodInfo, чтобы при помощи метода Invoke() вызвать метод TurboBoost(). MethoInfo.Invoke() требует, чтобы все параметры, которые нужно будет передать вызываемому методу, передавались Invoke() как массив объектов класса System.Object. TurboBoost() никакие параметры не нужны, поэтому можно просто передать значение типа nul1 (оно как раз и значит, что вызываемому методу параметры не передаются);
public static int Main(string[] args){
// Загружаем CarLibrary при помощи класса Assembly
// Получаем объект типа Туре
Type miniVan = a.GetType(“CarLibrary.MiniVan");
// Создаем объект класса MiniVan "на лету"
object obj = Activator.CreateInstance(miniVan);
// Получаем объект класса MethodInfo для метода TurboBoost()
MethodInfo mi = miniVan.GetMethod(“TurboBoost");
// Вызываем метод (передаем null вместо параметров)
mi.Invoke(obj, null);
return 0; }
В результате выполнится метод TurboBoost() для объекта класса MiniVan.