【发布时间】:2011-02-01 02:25:42
【问题描述】:
我们有一个插件系统,其中插件代码运行在与主进程不同的 AppDomain 上,使用 .NET 远程处理对象进行通信。
一个类类似于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 上(通过即时窗口验证),所有静态数据(例如 MyClass.Instance 和 HttpContext.Current)都已消失并且为空。我感觉 MyClass.Instance 以某种方式从插件 AppDomain 中检索到,但不确定如何解决。
我看到另一个建议RemotingServices.Marshal 的问题,但这似乎没有帮助,或者我使用不正确。 CommunicatingClass 是否可以像主 AppDomain 中的任何其他类一样访问所有静态方法和属性?
编辑:
PluginClass 有一个这样的实例:
public static PluginClass Create()
{
var appDomain = GetNewAppDomain();
var instance = (PluginClass)appDomain.CreateInstanceAndUnwrap(assembly, type);
instance.Communicator = new CommunicatingClass();
return instance;
}
编辑 2:
可能已经找到问题的根源。 MyClass.Instance 存储在 HttpContext.Current.Items 中(见上面的编辑)。
有什么方法可以让 HttpContext.Current 访问正确的 HttpContext 吗?我仍然想知道为什么,即使它正在 HttpContext.Current 的 AppDomain 中运行,CommunicatingClass.DoSomething,在调用 MyClass.Instance 时,会从 PluginClass 的 AppDomain 中检索东西(如果这有意义的话)。
【问题讨论】:
-
如果您不知道:远程处理已被弃用,取而代之的是 WCF。
-
如果您在 PluginClass 应用程序域中包含用于获取通信类引用的代码,这可能会有所帮助。
-
@John Saunders,WCF 如何与跨应用程序域通信一起工作?当客户端和服务器分开时是有意义的,但在这种情况下似乎不像透明远程代理那么容易。不过,我从未使用过 WCF,只是看了看。
-
@Snea:它有效。它完全取代了远程处理。
-
@John Saunders,您是否有文章或其他问题谈论如何使用远程处理将跨应用程序域通信迁移到 WCF,或者我应该在这个程度上问另一个问题?
标签: c# .net remoting appdomain