Architecture Net или что такое Microsoft.NET?




Пример AppDomain (Прикладная область)

При выполнении примера AppDomain (Прикладная область) получается выдача, показанная на рис. 8.1.

1.gif

Рис. 8.1. Выдача в примере AppDomain (Прикладная область)

Сначала выводится имя, поток и контекст прикладной области, заданной по умолчанию

AppDomain *currentDomain = AppDomain:: CurrentDomam;
Console::WriteLine(
"At startup, Default AppDomain is {0}
Threadld: {1}
"При запуске по умолчанию AppDomain - {0}
Threadld: {1}
Contextld {2}\n",
currentDomain->FrlendlyName,
Thread::CurrentThread->GetHashCode() .ToString(),
Thread::CurrentContext->ContextID.ToString());

Затем загружается и выполняется сборка Код из этой сборки только выводит строку, название прикладной области, в которую загружена сборка, а также название потока и контекста Необходимо отметить, что все это выполняется в прикладной области, создаваемой по умолчанию

int val = domain->ExecuteAssembly(
"TestApp\\bin\\Debug\\TestApp.exe", 0, args);
// параметры

Потом мы создадим экземпляр Customers (Клиенты) из сборки Customer (Клиент) в прикладной области, заданной по умолчанию Метод Createlnstance класса AppDomain (Прикладная область) возвращает экземпляр ObjectHandle Этот ObjectHandle можно передавать между прикладными областями без загрузки метаданных, ассоциированных с упакованным типом Если нужно использовать созданный экземпляр объекта, его следует распаковать, вызвав метод Unwrap (Развернуть) для объекта Ob] ectHandle

Objecthandle *on = currentDomain->Create!nstance(
"Customer", "01.NetCpp.Acme.Customers"), // Клиент
Customers *custs = // Клиенты
dynamic_cast<Customers *>(oh->Unwrap ());

Затем мы добавляем нового клиента, а потом перечисляем всех существующих клиентов Необходимо отметить, что и конструктор этого типа, и его методы выполняются в том же самом потоке и контексте, что и созданная по умолчанию прикладная область
Далее мы создаем новую прикладную область, а в ней — экземпляр того же типа, что и раньше

AppDomain *domain = AppDomain::CreateDomain(
"CreatedDomainl", 0, 0);
oh = domain->CreateInstance(
"Customer", "01.NetCpp Acme.Customers"); // Клиент
Customers *custs2 = dynamic_cast // Клиенты
<Customers *>(oh->Unwrap());

Необходимо отметить, что в результате вызова метода Createlnstance происходит вызов конструктора, который выполняется в новой прикладной области и поэтому в контексте, отличном от того, в котором был сделан вызов Createlnstance Однако выполнение этого вызова происходит в том же потоке, в котором был сделан вызов Createlnstance
Когда мы составляем список клиентов в этом новом объекте, мы получаем другой список клиентов И не удивительно, ведь это другой объект Customers (Клиенты) Тем не менее, метод составления списка клиентов выполняется в заданной по >молчанию прикладной области1
Используя RemotingServices: : IsTransparentProxy, можно увидеть, что ObjectHandle — это заместитель объекта Customers (Клиенты) в новой созданной прикладной области (AppDomain) Однако, если попытаться распаковать объект, чтобы получить дескриптор экземтяра, то в результате мы получим не указатель на заместитель, а фактическую объектную ссылку По умолчанию, объекты передаются по значению (копируются) из одной прикладной области в другую
Если объект Customers (Клиенты) — нельзя сериализовать (преобразовать в последовательную форму), то при попытке его скопировать будет запущено исключение Это исключение появляется при вызове метода Unwrap (Развернуть), а не Createlnstance Последний метод возвращает ссылку Копирование происходит только в том случае, если объект ObjectHandle распакован Если же объект не может быть преобразован в поспедоватечьную форму, он не может быть скопирован из одной прикладной области в другую
На следующем шаге будет создан новый поток, который создаст новую прикладную область, куда затем загружается и где выполняется какая-нибудь сборка Сборка начинает выполняться со своей точки входа — подпрограммы Мат (Главная) класса

AppDomainTest
AppDomain *domain = AppDomain::CreateDomain( "CreatedDomain2", 0, 0);
String * args[] = new String *[!];
// Строка * параметры [] = новая Строка * [1];
args[0] = "MakeReservation"; // параметры [О]
int val = domain->ExecuteAssembly(
"TestApp\\bin\\Debug\\TestApp.exe", 0, args); // параметры
AppDomain::Unload(domain);

Подпрограмма Main (Главная) загружает сборку Hotel (Гостиница) в созданную прикладную область. В этом примере приложение TestApp. exe реализовано на С#. После загрузки оно запрашивает метаданные сборки для получения информации о типе HotelBroker. Затем эта информация используется для создания объекта HotelBroker. Класс HotelBroker помечен атрибутом синхронизации. В результате конструктор HotelBroker и метод MakeReservation работают в контексте, отличном от заданного по умолчанию.

Assembly a = AppDomain.CurrentDomain.Load("Hotel") ;
// Сборка - Загрузить ("Гостиница"); Type typeHotelBroker =
а.GetType("01.NetCpp.Acme.HotelBroker"); HotelBroker hotelBroker =
(HotelBroker)Act vator.CreateInstance(typeHotelBroker); DateTime date = Date
Time.Parse("12/2/2001"); // дата = DateTime.
Синтаксический анализ ("12/2/2001");
ReservationResult rr = hotelBroker.MakeReservation(1,
"Boston", "Sheraton", date, 3);
// "Бостон", "Шератон", дата, 3);
Console.WriteLine("\tReservation Id: {0}", // Идентификатор
rr.Reservationld);