.NET应用程序域只传递值类型对象的解决方法

3
我正在开发一个.net应用程序,它严重依赖于插件。该应用程序本身包含与远程服务器的连接。
最近,我研究了应用程序域,并将其视为将插件代码与应用程序的其余部分隔离的理想解决方案。
然而,有一个很大的缺点,使我无法实现应用程序域来托管插件。似乎没有办法传递对象引用到另一个应用程序域中,以传递对连接对象的引用。
我希望有人能给我提供解决方法,这样我就可以传递对该对象的引用。
注意:创建代理不可行,连接层已充当代理,因为类是自动生成的。
注意2:由于System.AddIn在紧凑框架上不可用,因此不能使用它。
3个回答

5

你尝试过从MarshalByRefObject派生吗?这会破坏继承层次结构,但我认为这正是你想要的。

来自文档:

MarshalByRefObject是跨应用程序域通信的基类,通过使用代理交换消息。没有继承自MarshalByRefObject的对象隐式地按值进行编组。当远程应用程序引用按值编组对象时,对象的副本会通过应用程序域边界传递。在本地应用程序域的范围内直接访问MarshalByRefObject对象。当远程应用程序域中的应用程序第一次访问MarshalByRefObject时,将向远程应用程序传递代理。对代理的后续调用将被编组回到驻留在本地应用程序域中的对象上。当类型跨应用程序域使用并且对象的状态不得复制时,必须从MarshalByRefObject继承类型,因为对象的成员在创建它们的应用程序域之外不可用。
根据我的经验,跨应用程序域边界的操作非常受限制 - 最好只使用原始类型、字符串和两者的数组来进行尽可能少的操作。这可能是因为我在处理多个应用程序域方面缺乏经验,但这只是一个提醒,需要小心谨慎。

我看到它可能会搞乱我的继承层次结构。 我会去检查一下,谢谢。 - Stormenet
好的,我尝试了一下,看起来很有前途。但是,大多数插件返回一个用户控件,需要在主应用程序中托管,这似乎非常棘手:s - Stormenet
是的,做跨域用户界面的东西确实很难。你看过.NET 3.5 System.AddIn吗?我不知道它对你是否有用,但可能值得一看... http://blogs.msdn.com/zifengh/ - Jon Skeet

1

如果要在应用程序域之间访问同一实例,则必须从MarshalByRefObject继承。这样做,对对象的每个方法调用(包括属性等)实际上都是对其他应用程序域的远程调用。这有帮助吗?


1

请注意,MarshalByRefObject代理的清理是基于租约进行的。简而言之,如果您在特定时间内不使用该对象,它将被回收。您可以通过覆盖InitializeLifetimeService来控制此过程,以返回与您需求匹配的租约对象。如果返回null,则有效禁用了租约,然后只有在卸载AppDomain时才会回收该对象。


这非常有帮助,我正在使用应用程序域,但我的MarshallByRefObject在我完成之前就被清理了! - millejos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接