Атрибуты, сборки, рефлексия
Версия сборки
Эта характеристика имеется у каждой сборки, несмотря на то, что частной сборке она и ни к чему.
Версию можно "подсмотреть" в манифесте сборки с помощью IlDasm.exe. Можно было бы для пущей крутизны кода поле Version проинициализировать непосредственно (дело хозяйское).
И тут открываются несколько проблем:
- в манифесте версия задается последовательностью цифр, разделенных между собой двоеточием. Однако при формировании поля Version эти цифры следует разделять точкой;
- если сборка уникальна и среда разработки приложения ничего не знает о других версиях данной сборки – в поле Version можно спокойно забивать любые четверки чисел. Лишь бы требования формата были соблюдены;
- две одноименных частных сборки с разными версиями в раздел References третьей сборки загрузить не получается. Одноименные файлы с одинаковым расширением в один каталог не помещаются. Невзирая на версии.
Следующий шаг: загружаем сборку в память.
Используется блок try, поскольку загружаемую сборку можно и не найти.
При загрузке сборки известно ее расположение (application directory), однако с расширением имени могут возникнуть проблемы. Действует такой алгоритм "поиска" (и называть-то это поиском как-то неудобно):
Среда выполнения .NET пытается обнаружить файл с расширением .dll.
В случае неудачи среда выполнения .NET пытается обнаружить файл с расширением .exe.
В случае неудачи – предпринимаются ДРУГИЕ алгоритмы поиска.
Файл конфигурации приложения
Так что за ДРУГИЕ алгоритмы?
Все зависит от файла конфигурации приложения. В этом файле можно явным образом сформулировать особенности приложения. В частности, явным образом указать место расположения загружаемой сборки.
Файл конфигурации – это текстовый файл со странным именем <ИмяФайла.Расширение>.config, в котором размещаются в строго определенном порядке теги, прописанные на языке XML.
Среда выполнения .NET умеет читать XML.
Утверждается, что если расположить частные сборки в других подкаталогах приложения, нежели bin\Debug, то с помощью файла конфигурации эти сборки исполняющая среда БЕЗ ТРУДА обнаружит. Однако не находит. Может быть, я что-то не так делаю?
Файл AssemblyStarter.exe.config: <configuration> <runtime> <assemblyBinding xmlns="urn:schemas–microsoft–com:asm.v1" > <probing privatePath="XXX\YYY"/> </assemblyBinding> </runtime> </configuration>
Общедоступная сборка
Строгое имя общедоступной сборки состоит из:
- дружественного текстового имени и "культурной" информации;
- идентификатора версии;
- пары "Открытый/Закрытый ключ";
- цифровой подписи.
Делаем общую сборку.
- Сначала – ЧАСТНАЯ сборка.
using System; namespace SharedAssembly00 { // Summary description for Class1. public class Class1 { public Class1() { } public void f0() { Console.WriteLine("This is SharedAssembly00.f0()"); } } }
- Делаем пару "Открытый/Закрытый ключ".
Для этого в Visual Studio .NET 2003 Command Prompt командной строкой вызываем утилиту – генератор ключей:
D:\...>sn –k theKey.cnk
- В файле сборки AssemblyInfo.cs (таковой имеется в каждом проекте, ранее не использовался) дописываем в качестве значения ранее пустого атрибута AssemblyKeyFile полный путь к созданному утилитой sn файлу (в одну строчку):
[assembly: AssemblyKeyFile(@"D:\Users\WORK\Cs\AssemblyTest\Shared Assembly00\theKey.snk")]
- Компилируем сборку и наблюдаем манифест сборки, в котором появляется открытый ключ. Открытый ключ размещается в манифесте сборки. Закрытый ключ хранится в модуле сборки, содержащем манифест, однако в манифест не включается. Этот ключ используется для создания цифровой подписи, которая помещается в сборку. Во время выполнения сборки среда выполнения проверяет соответствие маркера открытого ключа сборки, запрашиваемой клиентом (приложением, запускающим эту сборку), с маркером открытого ключа самой сборки общего пользования из GAC. Такая проверка гарантирует, что клиент получает именно ту сборку, которую он заказывал.
Клиентское приложение Сборка общего пользования, установленная в GAC В манифесте клиента имеется ссылка на внешнюю сборку общего пользования. Маркер открытого ключа этой сборки отмечен тегом: :::::::::: .assembly extern SharedAssembly00 { .publickeytoken = (90 8E D8 5E 3E 37 72 08)// ...^>7r. .ver 1:0:1790:37888 } ::::::::::
Манифест сборки общего пользования в GAC содержит такое же значение ключа: 908ED85E3E377208
Его можно увидеть при исследовани и содержимого GAC (свойства элемента)
А закрытый ключ сборки общего пользования совместно с открытым ключом используется для создания цифровой подписи сборки и хранится вместе с подписью в самой сборке - Размещаем общедоступную сборку в GAC. Для этого либо используем утилиту gacutil.exe с ключом \i и именем сборки с полным путем в качестве второго параметра, либо просто перетаскиваем мышкой файл сборки в каталог, содержащий GAC. В случае успеха наблюдаем состояние GAC.