Создание доменов приложений

98

Один процесс способен обслуживать множество доменов приложений посредством статического метода AppDomain.CreateDomain(). И хотя необходимость в создании новых доменов приложений на лету в большинстве приложений .NET возникает крайне редко, важно в общем понимать, как это делается. Например, создаваемые динамические сборки должны устанавливаться в специальный домен приложения. Вдобавок многие API-интерфейсы, связанные с безопасностью .NET, требуют понимания того, каким образом создавать новые домены приложения для изолирования сборок на основе предоставляемых учетных данных безопасности.

Метод AppDomain.CreateDomain() имеет несколько перегруженных версий. Как минимум, ему требуется предоставить дружественное имя создаваемого домена приложения.

CLR-среда будет всегда загружать сборки в используемый по умолчанию домен приложения по мере необходимости. Однако в случае создания вручную специальных доменов приложений, эти сборки можно загружать в данные домены с помощью метода AppDomain.Load(). Кроме того, существует метод AppDomain.ExecuteAssembly(), который позволяет загрузить сборку *.ехе и выполнить метод Main().

Важно отметить, что выгружать отдельные сборки .NET в CLR-среде не разрешено. Однако с помощью метода AppDomain.Unload() можно производить избирательную выгрузку определенного домена приложения из обслуживающего процесса. В этом случае вместе с доменом приложения будут выгружаться и все содержащиеся в нем сборки.

Давайте рассмотрим процесс создания и выгрузки доменов приложений на конкретном примере:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            MakeNewDomain();
            Console.ReadLine();
        }

        static void MakeNewDomain()
        {
            // Создадим новый домен приложения
            AppDomain newD = AppDomain.CreateDomain("ProfessorWebAppDomain");
            InfoDomainApp(newD);
            // Уничтожение домена приложения
            AppDomain.Unload(newD);
        }

        static void InfoDomainApp(AppDomain defaultD)
        {
            Console.WriteLine("*** Информация о домене приложения ***\n");
            Console.WriteLine("-> Имя: {0}\n-> ID: {1}\n-> По умолчанию? {2}\n-> Путь: {3}\n",
                defaultD.FriendlyName,defaultD.Id,defaultD.IsDefaultAppDomain(),defaultD.BaseDirectory);

            Console.WriteLine("Загружаемые сборки: \n");
            // Извлекаем информацию о загружаемых сборках с помощью LINQ-запроса
            var infAsm = from asm in defaultD.GetAssemblies()
                         orderby asm.GetName().Name
                         select asm;
            foreach (var a in infAsm)
                Console.WriteLine("-> Имя: \t{0}\n-> Версия: \t{1}",a.GetName().Name, a.GetName().Version);
        }
    }
}
Пример создания доменов приложений

Запустив отладку данного проекта (нажатием <F5>), можно увидеть, что в каждый из доменов приложений будет загружаться много дополнительных сборок, которые необходимы Visual Studio для поддержки процесса отладки. Если просто запустить проект на выполнение (нажатием <Ctrl+F5>), будут выводиться только сборки, загруженные в каждый домен приложения.

Тем, кто привык работать с традиционными приложениями Windows, подобное поведение может показаться нелогичным (ведь оба домена приложений имеют доступ к одинаковому набору сборок). Однако следует помнить, что любая сборка загружается в домен приложения, а не напрямую в процесс.

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