Шрифт:
Сначала мы рассмотрим различия между одномодульными и многомодульными компоновочными блоками, а также между "приватными" и "общедоступными" компоновочными блоками. Затем мы выясним, как среда, выполнений .NET определяет параметры размещения компоновочного блока, и попытаемся понять роль GAC (Global Assembly Cache – глобальный кэш компоновочных блоков), файлов конфигурации приложения (файлы *.config), политики публикации компоновочных блоков и пространства имен System.Configuration.
Роль компоновочных блоков .NET
Приложения .NET строятся путем связывания произвольного числа компоновочных блоков. С точки зрения упрощенного подхода компоновочный блок является двоичным файлом, включающим свое описание, снабженным номером версии и поддерживаемым средой CLR (Common language Runtime – общеязыковая среда выполнения). Несмотря на тот факт, что компоновочные блоки .NET имеют такие же расширения (*.exe или *.dll), как и другие двоичные файлы Win32 (включая все еще используемые серверы COM), по сути, компоновочные блоки .NET имеют с ними очень мало общего. Поэтому для начала мы рассмотрим некоторые преимущества, обеспечиваемые форматом компоновочного блока.
Расширенные возможности многократного использования программного кода
При построений консольных приложений в предыдущих главах могло показаться, что в создаваемом вами выполняемом компоновочном блоке содержатся все функциональные возможности соответствующего приложения. На самом же деле ваши приложения использовали множество типов, предлагаемых всегда доступной библиотекой программного кода .NET, mscorlib.dll (напомним, что компилятор C# ссылается на mscorlib.dll автоматически), а также библиотекой System.Windows.Forms.dll.
Вы, наверное, знаете, что библиотека программного кода (также называемая библиотекой классов) представляет собой файл *.dll, содержащий типы, доступные для использования внешними приложениями. При создании выполняемого компоновочного блока используются компоновочные блоки, предлагаемые системой, а также пользовательские компоновочные блоки. При этом файл библиотеки программного кода не обязательно имеет вид *.dll, поскольку выполняемый компоновочный блок может использовать и типы, определенные во внешнем выполняемом файле. В этой связи файл *.exe тоже можно считать "библиотекой программного кода".
Замечание. До появления Visual Studio 2005 единственную возможность сослаться на выполняемую библиотеку программного кода обеспечивал флаг /reference компилятора C#. Но теперь ссылаться на компоновочные блоки *.exe позволяет и диалоговое окно Add Reference (Добавление ссылки) в Visual Studio 2005.
Независимо от того, как упакована библиотека программного кода, платформа .NET позволяет использовать типы в независимой от языка форме. Например, можно создать библиотеку программного кода в C# и использовать эту библиотеку в любом другом языке программирования .NET. При этом можно не только создавать экземпляры типов в рамках других языков, но и получить производные таких типов. Базовый класс, определенный в C#, можно расширить с помощью класса, созданного в Visual Basic .NET. Интерфейсы, определенные в Pascal .NET, могут реализовываться структурами, определенными в C#. Смысл в том, что при разделении единого и монолитного выполняемого программного кода на множество компоновочных блоков .NET вы получаете языково-нейтральную форму программного кода, пригодного для многократного использования.
Установка четких границ типов
Из главы 3 вы узнали о формальных понятиях, лежащих в основе любого пространства имен .NET. Напомним, что абсолютное имя типа строится путем добавления префикса пространства имен (например, System) к имени типа (например, Console). Однако, строго говоря, компоновочный блок, содержащий данный тип, задает параметры дальнейшей идентификации типа. Например, если у вас есть два компоновочных блока с разными названиями (скажем, MyCars.dll и YourCars.dll), которые определяют пространство имен (CarLibrary), содержащее класс SportsCar, то эти классы во "вселенной" .NET будут считаться разными типами.
Управление версиями
Компоновочным блокам .NET назначается состоящий из четырех частей числовой идентификатор версии, имеющий вид ‹главный номер версии›.‹дополнительный номер версии›.‹номер компоновки›.‹номер варианта› (если вы не укажете явно идентификатор версии с помощью свойства [AssemblyVersion], компоновочный блок автоматически получит идентификатор версии 0.0.0.0). Этот идентификатор в совокупности с необязательным значением открытого ключа позволяет множеству версий одного и того же компоновочного блока сосуществовать на одной и той нее машине в полной гармонии, Компоновочные блоки, обеспечивающие информацию об открытом ключе, называются строго именованными. Как будет показано в этой главе позже, при наличии строго заданного имени среда CLR способна гарантировать, что по запросу вызывающего клиента будет загружена именно та версия компоновочного блока, которая требуется.
Самоописание
Компоновочные блоки считаются единицами с частичным самоописанием, поскольку в них содержится информация о внешних компоновочных блоках, необходимых для правильного функционирования компоновочного блока. Так что если вашему компоновочному блоку требуются System.Windows.Forms.dll и System. Drawing.dll, то информация о них будет записана в манифест компоновочного блока. Вспомните из главы 1, что манифест – это блок метаданных, описывающих сам компоновочный блок (имя, версия, информация о внешних компоновочных блоках и т.д.).