Динамическая загрузка сборок

Приложение может загружать другие сборки из:

1. Каталога приложения (private-сборки).

2. Global Assembly Cache (GAC) (разделяемые сборки).

3. Конкретного файла на диске.

Первые два способа идентифицируют сборку по имени.

Полное имя сборки содержит, помимо собственно имени, также версию сборки, информацию о локализации (Culture) и открытый ключ сборки (PublicKeyToken). Вот пример имени сборки:

 

System.Drawing, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a

 

Полное имя (т.е. содержащее все компоненты имени) однозначно идентифицирует сборку и по нему можно будет её загрузить.

 

Assembly asm = Assembly.Load("System.Drawing, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");

 

Имя сборки может быть как полным, так и частичным. Частичное имя сборки позволяет задействовать специальный механизм поддержания версий сборок. Метод LoadWithPartialName класса Assembly загружает сборку по частичной информации о ней.

 

Assembly asm = Assembly.LoadWithPartialName("System.Drawing");

 

В данном случае передано только имя сборки. В соответствии с политикой версий будет выбрана и загружена наиболее подходящая сборка. Этот способ более гибок, т.к. позволяет управлять загрузкой сборок, задавая или опуская различные параметры. Например, если вы укажете номер версии, то сборки другой версии (пусть даже более поздней!) использоваться не будут. А если явно задать локализацию (культуру), то в будущем не нужно беспокоиться, что приложение случайно подключит новую версию сборки, не поддерживающую указанную локализацию.

Динамическая загрузка сборок из каталога приложения не требует указания полного имени сборки, достаточно краткого имени.

 

Assembly asm = Assembly.Load("MyAssembly"); // загрузка private-сборки

 

Функции Assembly.Load и Assembly.LoadWithPartialName при выборе подходящей сборки первым делом просматривают каталог приложения, отдавая предпочтение private-сборкам.

Примечание: Размещение сборок в каталоге приложения считается предпочтительным. Такой способ помогает предотвратить взаимное влияние приложений – "кошмар DLL".

Динамическая загрузка сборки по полному пути к файлу позволяет загрузить любую сборку в системе (не только private- или из GAC).

 

Assembly a = Assembly.LoadFrom("D:\\WINNT\\Microsoft.NET\\Framework\\v1.0.3705\\System.Drawing.dll");

 

Однако этот способ недостаточно гибок и вряд ли стоит его широко применять.

Динамическая загрузка типов

Теперь, когда сборка загружена, можно извлечь из неё информацию о типе. Для этого необходимо использовать так называемое "квалифицированное имя типа" (Assembly Qualified Type Name). Квалифицированное имя типа состоит из двух частей: полного имени типа и полного или частичного имени сборки. Для получения описания метаданных некоторого типа его квалифицированное имя передаётся в статический метод GetType класса Type. В случае успеха этот метод возвращает экземпляр класса Type.

 

Assembly a = Assembly.LoadWithPartialName("System.Drawing");

string strAssemblyQualifiedTypeName = "System.Drawing.Rectangle, " +

a.FullName;

Type type = Type.GetType(strAssemblyQualifiedTypeName);

 

В данном случае загрузка типа проведена в три этапа. Сначала загружена сборка, затем получено её полное имя и, только потом, получен объект Type. Эти этапы можно объединить. Если вы знаете полное имя сборки, можно использовать его для составления квалифицированного имени типа, которое можно напрямую передать методу Type.GetType().

 

Type type = Type.GetType("System.Drawing.Rectangle"

+ ", System.Drawing"

+ ", Version=1.0.3300.0"

+ ", Culture=neutral"

+ ", PublicKeyToken=b03f5f7f11d50a3a"

);

 

Исследование типа

Имея в руках объект Type, можно начинать исследовать структуру типа, который он описывает (перебирать поля, методы, события, свойства, вложенные типы).