Я пытаюсь выполнить метод из объекта, который загружается из сборки, которая динамически генерируется с CompilerResults.CompiledAssembly
.Однако мне нужно, чтобы эта сборка имела ограниченные разрешения, потому что методы, которые она содержит, имеют непредвиденное поведение.
Я много раз искал, и в документах Microsoft предлагается использовать функции безопасности, предоставляемые .NET Framework 4. Это - один из многих источников, которые я читал о песочнице, где используется другой AppDomain
с ограниченными разрешениями.Теоретически я могу создать экземпляры из класса в сборке, которая загружена в ограниченном AppDomain
, и этот экземпляр будет считаться удаленным объектом.
Чтобы использовать новый объект в качестве ссылки, создается проксивнутренне, когда вы пытаетесь получить доступ к объекту, если класс расширяет класс MarshalByRefObject
.В моем случае класс, который расширяет MarshalByRefObject
, находится на вершине иерархии.
Упрощенная версия кода, основанная на ссылке, которую я упомянул ранее:
var permissionSet = ...;
var dllPath = ...;
// Create the AppDomainSetup
var info = new AppDomainSetup
{
// Set the path to the assembly to load.
ApplicationBase = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
};
var strongName = assembly.Evidence.GetHostEvidence<StrongName>();
// Create the domain
var sandboxDomain = AppDomain.CreateDomain("RestrictedDomain", null, info, permissionSet, new StrongName[] { strongName });
var handle = Activator.CreateInstanceFrom(sandboxDomain, dllPath, "MyNamespace.MyClass");
var myLoadedTypeInstance = handle.Unwrap() as MyClass;
Приведенный выше код работает, сборка загружается в AppDomain
(может делать это только с указанием местоположения dll, а не его имени).Но когда я пытаюсь использовать метод из myLoadedTypeInstance
с двумя сериализуемыми параметрами, я получаю исключение.Вызов похож на myLoadedTypeInstance.MyMethod(param1, param2)
, исключение составляет:
"Метод InitializeLifetimeService не поддерживается на этом прокси-сервере, это может произойти, если метод не помечен с помощью OperationContractAttribute или если тип интерфейса непомечен ServiceContractAttribute. "
Некоторые детали:
- Не знаю, имеет ли это значение, но первый параметр - это объекты, которые содержат свойство типа
TChannel
, созданный с помощью ChannelFactory<T>.CreateChannel()
. - Меня смущает, что код не запускается при инициализации службы времени жизни, но если я использую
RemotingServices.GetLifetimeService(myLoadedTypeInstance) as ILease
, я могу получить доступ ко всей информации о времени жизни удаленного объекта. - IЯ также пытался обработать его как удаленный объект, явно используя
Activator.GetObject()
с URL-адресом, предоставленным RemotingServices.GetObjectUri(myLoadedTypeInstance)
, что является избыточным, потому что я в итоге создал два экземпляра объекта.Но это был отчаянный ход с таким же окончанием. - Я не могу отладить это с VisualStudio, так как он выполняется в отдельном процессе.