Шрифт:
Ниже выводятся сигнатуры всех методов, доступных через ссылку на любой интерфейс класса Account. Это и оба метода, реализованные в классе Account, и методы, унаследованные от System.Object.
Регистрация сборки в Global Assembly Cache
GAC — Global Assembly Cache, это то место, где можно развертывать сборки, которые должны быть доступны многим клиентам. Для развертывания сборки в GAC ее нужно подписать. Точнее, сборке присваивается версия, ее содержимое хешируется и хешированное значение шифруется личным ключом разработчика. В сборку (в ее манифест), включаются версия сборки, шифрованный хеш — электронная подпись, публичный ключ. В результате, благодаря наличию публичного ключа, можно проверить сохранность сборки, т. е. перед запуском клиентского приложения удостовериться, что именно с этой сборкой данное клиентское приложение было откомпилировано.
Ниже приведены все необходимые команды, обеспечивающие подписание сборки и ее регистрацию в GAC:
>csc /t: module MyServer.cs
>sn — k my.snk
>al /out: MyServer.dll MyServer.netmodule /keyfile: my.snk
>gacutil — i MyServer.dll
>sn — Tp MyServer.dll
Public key is
002400000480….
Public key token is 047772996d01a6d4
Для получения подписанной сборки (сборки со строгим именем) нужно откомпилировать код серверас параметром /t: module. В результате получим модуль MyServer.netmodule, содержащий (как и сборка) код на MSIL, но не содержащий (в отличие от сборки) манифеста.
Далее генерируется (если не была сгенерирована ранее) пара ключей — личный и публичный ключи, с помощью утилиты sn (strong name). Эта пара записывается в файл my. snk.
На следующем этапе компоновщик сборки al (assembly linker) формирует подписанную сборку MyServer. dll, используя модуль MyServer.netmodule и файл с ключами my.snk.
Для регистрации сборки в GAC можно использовать утилиту gacutil.
Для работы с подписанной сборкой клиент должен знать ее версию и публичный ключ (или его хешированное значение — токен публичного ключа). Последнее можно получить с помощью утилиты sn с параметром —Tр, указав подписанную сборку.
В следующем примере демонстрируется клиент, который может воспользоваться зарегистрированной в GAC сборкой. Кроме этого, в этом примере демонстрируется так называемая динамическая ссылка на сборку.
В случае продемонстрированной в предыдущем примере статической ссылки, которую можно было бы применить и в этом случае (в случае сборки зарегистрированной в GAC), клиент связывается с нужной сборкой на этапе компиляции. В этом случае в манифест сборки клиента записывается вся нужная информация об используемых им сборках. Это позволяет еще до запуска клиента узнать — имеются ли в наличии нужные клиенту компоненты. Благодаря использованию подписанной сборки при ее наличии можно гарантировать ее совместимость с клиентом.
Но иногда нужно связаться со сборкой динамически, в процессе исполнения клиента. В этом случае на этапе компиляции наличие нужной сборки (и нужного типа в данной сборке) не проверяется.
using System;
using System.Reflection;
public class MyApp {
public static void Main {
Assembly assem = Assembly.Load("MyServer, " +
"Version=0.0.0.0, " +
"Culture=neutral, " +
"PublicKeyToken=047772996d01a6d4");
Type accountType = assem.GetType("MyServer.Account");
if (accountType!= null) {
MethodInfо addMethod = accountType.GetMethod("Add");
MethodInfo totalMethod =
accountType.GetMethod("Total");
Object obj = Activator.CreateInstance(accountType);
Object [] args = new Object[1];
args [0] = 3;
if (addMethod!= null){
addMethod.Invoke(obj, args);
args [0] = 5;
addMethod.Invoke(obj, args);
}
if (totalMethod!= null)
Console.WriteLine("Total = {0}",
totalMethod.Invoke(obj, null));
}
}
}
В данном примере статический метод Load класса Assembly загружает из GAC сборку с заданным именем, версией (по умолчанию 0.0.0.0), культурой (по умолчанию neutral) и токеном публичного ключа. Далее, используя механизм рефлексии, получаем ссылку на объект типа Tуре, содержащий всю информацию о классе Account из данной сборки. Если информация об этом типе имеется в загруженной сборке, получаем информацию о методах Add и Total. Потом создаем экземпляр класса Account и формируем массив аргументов. В данном случае массив состоит из одного элемента со значением 3.
Если метод Add реализован в классе Account, вызываем этот метод на построенном объекте, передавая ему сформированный массив аргументов. Модифицируем этот массив, занося в него 5, и еще раз вызываем метод Add.
И, наконец, если метод Total также реализован, вызываем его без аргументов и выводим полученное значение на консоль.
Дополнительный комментарий по поводу обновления версий компонентов. Как было отмечено выше, при использовании статической ссылки на подписанную сборку в манифесте клиента сохраняется хешированное значение сборки, с которой был откомпилирован этот клиент, что делает невозможным его запуск с другой версией этой же сборки. Тем не менее есть возможность связать клиента с более свежей версией сборки без его перекомпиляции. Для этого используются конфигурационные файлы, но их обсуждение находится за пределами данного курса.