Многофайловые сборки

83

Многофайловая сборка - это коллекция взаимосвязанных модулей, которые развертываются и снабжаются версией в виде цельной логической единицы. В IDE-среде Visual Studio никакого отдельного шаблона проекта для создания многофайловой сборки на C# не предусмотрено. Для создания такового пока что должен использоваться компилятор командной строки (csc.exe).

Рассмотрим этот процесс на примере, создав многофайловую сборку по имени Car. В главном модуле этой сборки (car.dll) будет содержаться единственный тип класса SportCar и соответствующий манифест, который указывает на наличие дополнительного файла *.netmodule по имени auto.netmodule, содержащего еще один класс Auto. Хотя физически оба класса размещаются в отдельных двоичных файлах, пространство имен у них будет одно — Car. И, наконец, оба класса будут создаваться на C# (хотя, конечно же, вполне допустимо использовать другие языки). Для начала откроем простой текстовый редактор и создадим следующее определение для класса Auto, после чего сохраним его в файле с именем auto.cs:

using System;

namespace Car
{
    public class Auto
    {
        public void AutoInfo()
        {
            Console.WriteLine("Информация об автомобиле: ");
        }
    }
}

Чтобы скомпилировать этот класс в .NET-модуль, откройте в Visual Studio 2010 окно командной строки, перейдите в папку, где был сохранен файл auto.cs, и введите следующую команду (опция module флага /t указывает, что должен быть создан файл *.netmodule, а не *.dll или *.ехе):

csc.exe /t:module auto.cs

В папке с файлом auto.cs появится новый файл по имени auto.netmodule. Теперь давайте создадим новый файл sportcar.cs со следующим определением класса:

using System;

namespace Car
{
    public class SportCar
    {
        public void InfoSportCar()
        {
            Console.WriteLine("Audi R8");
        }
    }
}

Поскольку было решено, что главный модуль в этой многофайловой сборке будет называться car.dll, осталось только скомпилировать sportcar.cs с использованием соответствующих опций /t: library и /out:. Чтобы включить информацию о двоичном файле auto.netmodule в манифест сборки, также потребуется добавить соответствующий флаг /addmodule. Полностью необходимая команда выглядит следующим образом:

csc /t:library /addmodule:auto.netmodule /out:car.dll sportcar.cs

После выполнения этой команды в каталоге должен появиться главный модуль car.dll, а также второстепенный двоичный файл auto. netmodule.

Теперь откроем файл auto.netmodule в утилите ildasm.exe. Сразу же можно будет заметить, что в нем содержится манифест уровня модуля, единственной задачей которого является перечисление всех внешних сборок, которые упоминаются в кодовой базе. Поскольку в классе Auto был практически добавлен только вызов Console.WriteLine(), обнаружится следующая ключевая информация:

Манифест уровня модуля

Далее откроем в ildasm.exe файл главного модуля car.dll и изучим содержимое манифеста уровня всей сборки. В нем важно обратить внимание, что маркер .file используется для представления информации о других ассоциируемых с многофайловой сборкой модулях (в данном случае — auto.netmodule), а маркеры .class extern — для перечисления имен внешних типов, которые упоминаются как используемые во второстепенном модуле (в данном случае — Auto). Ниже приведена соответствующая информация:

Манифест уровня всей сборки

Использование многофайловой сборки

Пользователям многофайловой сборки нет никакого дела до того, состоит ли сборка, на которую они ссылаются, из многочисленных модулей. Чтобы не усложнять пример, построим новое клиентское приложение на языке C# в командной строке. Для начала создадим новый файл по имени Client.cs со следующим определением модуля и сохраним его в месте, где находится многофайловая сборка:

using System;
using Car;

class Program
{
    static void Main()
    {
        SportCar obj = new SportCar();
        obj.InfoSportCar();

        // Здесь будет загружаться модуль auto.netmodule
        Auto obj1 = new Auto();
        obj1.AutoInfo();
        Console.ReadLine();
    }
}

Чтобы скомпилировать эту исполняемую сборку в командной строке, запустим компилятор csc.ехе с помощью следующей команды:

csc /r:car.dll Client.cs

Обратите внимание, что при добавлении ссылки на многофайловую сборку компилятору необходимо указать только имя главного модуля (второстепенные модули *.netmodule будут загружаться CLR-средой по требованию, когда возникнет необходимость в их использовании клиентским кодом). Сами по себе модули *.netmodule не обладают никаким индивидуальным номером версии и потому не могут напрямую загружаться CLR-средой. Отдельные модули *.netmodule могут загружаться только главным модулем (например, файлом, в котором содержится манифест сборки).

Пройди тесты
Лучший чат для C# программистов