#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.