«Невозможно преобразовать прозрачный прокси в тип» при использовании AppDomain.Метод CreateInstanceAndUnwrap

#c# #appdomain

#c# #appdomain

Вопрос:

Я получаю эту ошибку при попытке получить экземпляр класса в отдельном домене приложения. Вот код:

 string assemblyName = Assembly.GetExecutingAssembly().FullName;
string typeName = "Namespace.ClassName";

AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
SecurityZone zone = SecurityZone.MyComputer;

// Set up the Evidence
Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
Evidence evidence = new Evidence(baseEvidence);
evidence.AddAssembly(assemblyName);
evidence.AddHost(new Zone(zone));

AppDomain app = AppDomain.CreateDomain("Processor AppDomain", evidence, setup);
core = (Core)app.CreateInstanceAndUnwrap(assemblyName, typeName);
  

Оба класса (вызывающий и called) находятся в одной сборке (COM dll).

Итак, кто-нибудь знает, в чем причина этого исключения? Спасибо за любой ответ.

Комментарии:

1. Вы уверены, что typeName относится к Core типу? Что показывает отладчик, когда вы смотрите на результат CreateInstanceAndUnwrap() без приведения?

2. Спасибо за ответ, svick. typeName действительно относится к Core , иначе я получу другое исключение типа FileNotFoundException или TypeLoadException . Когда я изменил последнюю строку этого примера на Object core = app.CreateInstanceAndUnwrap(assemblyName, typeName); и отладил ее, все шло по правильному сценарию — поля основного класса были инициализированы, конструктор вызван и объект возвращен. Но этот возвращаемый объект System.Runtime.Remoting.Proxies.__TransparentProxy по типу для вызывающего класса. и, похоже, я не смог привести этот объект к Core типу.

3. Я не уверен, что вы можете сделать то, чего пытаетесь достичь. Целью создания объекта в отдельном домене приложения является изоляция частей вашего приложения. Используя реализацию, которая находится во втором AppDomain, вы пытаетесь нарушить сортировку и изоляцию, не так ли?

4. Хорошее предположение, но есть некоторые условия, чтобы думать, что AppDomain должен предоставлять удобные методы для работы со связанными объектами, и CreateInstanceAndUnwrap метод является одним из них. Вы можете видеть, что я пытаюсь сделать то же самое, что опубликовано на msdn.microsoft.com/en-us/library/3c4f1xde.aspx (смотрите пример).

5. Ваш тип, который вы пытаетесь создать в новом домене приложения, отмечен Serializable или ваш тип наследует MarshalByRefObject тип?

Ответ №1:

Как ваше приложение ссылается на com dll? Это тоже .net dll? Если ваше приложение ссылается на него как на проект, а также зарегистрировано как com dll, то есть вероятность, что ваше приложение ссылается на две разные копии dll, и в этом случае оно будет рассматривать ваши основные классы как два отдельных класса, поскольку они находятся в разных DLL. Вы могли бы рассмотреть возможность подключения события AssemblyLoad appdomains для отладки этого и проверки местоположения загружаемой сборки.

Комментарии:

1. Моя сборка представляет собой .Net COM dll, которая используется из проекта c . Как я уже сказал, оба класса (вызывающий и called) находятся в одной сборке. В этом случае я не понимаю, почему будет другая сборка. Когда я отлаживал оба класса (вызывающий и called) и выполнял Assembly.GetExecutingAssembly().Location , он вернул одинаковый результат для обоих классов. Надеюсь, я правильно понял вашу идею…

2. Почему бы вам не попробовать использовать AppDomain. CreateInstanceFromAndUnwrap, который позволит вам указать путь к dll.