Замечание. К этому моменту, наверное, уже не нужно повторять, что для просмотра программного кода CIL компоновочного блока, метаданных типов иди манифеста можно использовать ildasm.exe. Я предполагаю, что вы будете часто использовать ildasm.exe при изучении примеров этой главы.
Необязательные ресурсы компоновочного блока
Наконец, компоновочный блок .NET может содержать любой набор встроенных ресурсов, таких как, например, пиктограммы приложении, графические файлы, звуковые фрагменты или таблицы строк. Платформа .NET обеспечивает поддержку сопутствующих компоновочных блоков, которые не содержат ничего, кроме локализованных ресурсов. Это может понадобиться тогда, когда требуется предоставить ресурсы на разных языках (английском, немецком и т.д.) при создании программного обеспечения, используемого в разных странах. Тема создания сопутствующих компоновочных блоков выходит за рамки этой книги, но при изучении GDI+ в главе 20 вы узнаете, как встроить ресурсы приложения в компоновочный блок.
Одномодульные и многомодульные компоновочные блоки
Компоновочный блок можно скомпоновать из одного или нескольких модулей. Модуль – это просто обобщающий термин для обозначения двоичных файлов .NET. В большинстве случаев компоновочный блок компонуется из одного модуля. В таком случае наблюдается взаимно однозначное соответствие между (логическим) компоновочным блоком и лежащим в его основе (физическим) двоичным файлом (отсюда и появляется термин одномодульный компоновочный блок ).
Одномодульные компоновочные блоки содержат все необходимые элементы (информация: заголовка, программный код CIL, метаданные типов, манифест и требуемые ресурсы) в одном пакете *.exe или *.dll. На рис. 11.3 показана композиционная схема одномодульного компоновочного блока.
Многомодульный компоновочный блок, напротив, является набором .NET-файлов *.dll, которые инсталлируются как одна логическая единица и контролируются по единому идентификатору версии. Формально один из этих файлов *.dll называется первичным модулем, он содержит манифест компоновочного блока (а также необходимый программный код CIL, метаданные, информацию заголовка и опциональные ресурсы). Манифест первичного модуля содержит записи о каждом из связанных файлов *.dll, от которых он зависит.
Рис. 11.3. Одномодульный компоновочный блок
По соглашению о выборе имен вторичные модули в многомодульном компоновочном блоке имеют расширение *.netmodule, однако это не является непременным требованием CLR. Вторичные файлы *.netmodule также содержат CIL-код и метаданные типов, а также манифест уровня модуля, в котором просто записана информация о внешних компоновочных блоках, необходимых для данного конкретного модуля.
Главное преимущество построения многомодульных компоновочных блоков заключается в том, что они обеспечивают очень эффективный способ загрузки содержимого. Предположим, например, что у нас есть машина, которая ссылается на удаленный многомодульный компоновочный блок, состоящий из трех модулей, причем первичный модуль установлен на машине клиента. Если клиент потребует тип из вторичного удаленного файла *.netmodule, среда CLR загрузит двоичный выполняемый файл на локальную машину по требованию в специальное место, называемое кэшем загрузки. Если каждый файл *.netmodule имеет объем 1Мбайт, я уверен, вы поймете, в чем здесь преимущество.
Другим преимуществом многомодульных компоновочных блоков является то, что для них можно создавать модули на разных языках программирования .NET (что очень удобно в больших корпорациях, где разные подразделения могут отдавать предпочтение разным языкам .NET). После компиляции отдельных модулей эти модули можно логически "связать" в один компоновочный блок, используя, например, такой инструмент, как компоновщик (al.exe).
В любом случае следует понимать, что модули, которые образуют многомодульный компоновочный блок, не связаны непосредственно в один (больший) файл. Скорее, многомодульные компоновочные блоки связаны только логически информацией, содержащейся в манифесте первичного модуля. На рис. 11.4 показана схема многомодульного компоновочного блока, состоящего из трех модулей, каждый из которых написан на своем языке программирования .NET.
Рис. 11.4. Первичный модуль записывает информацию о вторичных модулях в манифест компоновочного блока
Читать дальше