В моем домене приложений по умолчанию (с полным доверием) я хочу создать домен приложений для песочницы и подписаться на событие в нем:
class Domain : MarshalByRefObject
{
public event Action TestEvent;
}
Domain domain = AppDomainStarter.Start<Domain>(@"C:\Temp", "Domain", null, true);
domain.TestEvent += () => { }; // SecurityException
Сбой подписки с сообщением «Сбой запроса разрешения типа« System.Security.Permissions.ReflectionPermission, mscorlib, Version = 4.0.0.0 ... ».»
(определение AppDomainStarter см. мой ответ на другой вопрос .)
Обратите внимание, что ApplicationBase
C: \ Temp - это НЕ папка, содержащая сборку, содержащую домен. Это намеренно; Моя цель состоит в том, чтобы загрузить вторую стороннюю ненадежную сборку внутри нового AppDomain, и эта вторая сборка находится в C: \ Temp (или где-либо еще, возможно, даже в сетевой папке). Но прежде чем я смогу загрузить вторую сборку, мне нужно загрузить класс Domain
внутри нового домена приложений. Это успешно, но по какой-то причине я не могу подписаться на событие через границу AppDomain (я могу вызывать методы, но не подписываться на события).
ОБНОВЛЕНИЕ : Очевидно, что при подписке на событие в песочнице AppDomain и метод подписчика, и класс, содержащий подписчика, должны быть общедоступными. Например:
public static class Program
{
class Domain : MarshalByRefObject
{
public event Action TestEvent;
public Domain() { Console.WriteLine("Domain created OK"); }
}
static void Main()
{
string loc = @"C:\Temp";
Domain domain = AppDomainStarter.Start<Domain>(loc, "Domain", null, true);
// DIFFERENT EXCEPTION THIS TIME!
domain.TestEvent += new Action(domain_TestEvent);
}
public static void domain_TestEvent() { }
}
Однако я все еще не могу подписаться на событие. Новая ошибка: «Не удалось загрузить файл или сборку» TestApp, Version = 1.0.0.0, Culture = нейтральный, PublicKeyToken = null 'или одна из его зависимостей. Система не может найти указанный файл. "
В некотором смысле, это имеет смысл, потому что я указал «неправильную» папку «C: \ Temp» в качестве ApplicationBase моего нового AppDomain, но в некотором смысле это не имеет никакого смысла, потому что сборка «TestApp» уже загружен в оба домена приложений . Как это возможно, что CLR не может найти сборку, которая уже загружена?
Более того, не имеет значения, если я добавлю разрешение на доступ к папке, содержащей мою сборку:
string folderOfT = Path.GetFullPath(Path.Combine(typeof(T).Assembly.Location, ".."));
permSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read, folderOfT));
// Same exception still occurs
Я могу «исправить» проблему, используя другое значение для AppDomainSetup.ApplicationBase
:
string loc = Path.GetFullPath(Assembly.GetExecutingAssembly().Location + @"\..");
Это исключает исключение, но я не могу использовать это «решение», поскольку цель AppDomain состоит в том, чтобы загрузить ненадежную сборку из папки, отличной от папки, содержащей мою собственную сборку. Следовательно, loc
должна быть папкой, содержащей ненадежную сборку, а не той, в которой содержится моя сборка.