У нас есть плагиновая система, в которой код плагина запускается на отдельном AppDomain из основного процесса, используя удаленное взаимодействие .NET для объектов для связи..NET Remoting и HttpContext.Current
Один класс похож на HttpContext.Current (который также страдает от проблемы) (редактировать, фактическая реализация):
public class MyClass
{
public static MyClass Instance
{
get
{
if(HttpContext.Current != null)
return HttpContext.Current.Items["MyClassInstance"];
}
set
{
if(HttpContext.Current != null)
HttpContext.Current.Items["MyClassInstance"] = value;
}
}
}
Тогда мы имеем сообщающийся объект, который наследуется от MarshalByRefObject:
public class CommunicatingClass : MarshalByRefObject, ICommunicatingClass
{
public void DoSomething()
{
MyClass.Instance.DoSomething();
}
}
CommunicatingClass создан на основном AppDomain и отлично работает. Затем, есть класс плагин, который создается на его AppDomain и дал экземпляр CommunicatingClass:
public class PluginClass
{
public void DoSomething(ICommunicatingClass communicatingClass)
{
communicatingClass.DoSomething();
}
}
Проблема заключается в том, что даже если CommunicatingClass находится на главной AppDomain (проверено с Immediate Window), все статические данные, такие как MyClass.Instance и HttpContext.Current, исчезли и имеют значение null. У меня такое ощущение, что MyClass.Instance каким-то образом извлекается из плагина AppDomain, но я не уверен, как это решить.
Я видел еще один вопрос, который предложил RemotingServices.Marshal
, но это не помогло, или я использовал его неправильно. Есть ли способ, которым CommunicatingClass может получить доступ ко всем статическим методам и свойствам, подобным любому другому классу в главном AppDomain?
Edit:
PluginClass дается пример, как это:
public static PluginClass Create()
{
var appDomain = GetNewAppDomain();
var instance = (PluginClass)appDomain.CreateInstanceAndUnwrap(assembly, type);
instance.Communicator = new CommunicatingClass();
return instance;
}
Edit 2:
могли бы найти источник проблемы. MyClass.Instance хранится в HttpContext.Current.Items (см. Выше).
Есть ли вообще способ, которым HttpContext.Current может получить доступ к правильному HttpContext? Мне все еще интересно, почему, хотя он запускается в AppDomain HttpContext.Current, CommunicatingClass.DoSomething при вызове MyClass.Instance извлекает данные из AppDomain от PluginClass (если это имеет смысл).
В случае, если вы не знаете: Remoting является устаревшим в пользу WCF. –
Это может помочь, если вы включили код, который вы используете, чтобы получить ссылку на communicationClass в домене приложения PluginClass. – JohnOpincar
@ Джон Сондерс, Как работает WCF с перекрестной связью? Это имеет смысл, когда клиент и сервер разделены, но не похоже, что в этом случае было бы проще, чем прозрачные удаленные прокси. Я никогда не работал с WCF, а просто смотрел на него. – Snea