用于将 POCO 实例公开给其他 AppDomain 的通用容器 - 它是如何工作的?
Posted
技术标签:
【中文标题】用于将 POCO 实例公开给其他 AppDomain 的通用容器 - 它是如何工作的?【英文标题】:Generic container for exposing POCO instances to other AppDomains - how does it work? 【发布时间】:2009-04-30 12:55:32 【问题描述】:我对来自另一个 SO 线程的 this 回答很感兴趣,我希望有人可以帮助我阐明这个概念。
假设我有一个主 AppDomain 和一堆子 AppDomain,它们由主 AppDomain 创建和初始化。在伪代码中:
主应用域:
class Parent
public void InitChildren(IList<ChildInfo> children)
foreach (var childInfo in children)
var ad = CreateNewChildAppDomain();
var child = (Child)ad.CreateInstanceAndUnwrap(typeof(Child));
child.Init(this);
public void Register(BasePoco info)
// Do something with info.
子应用域:
class Child : MarshalByRefObject
public void Init(Parent parent)
parent.Register(new Container<MyInfo>(new MyInfo()));
class MyInfo : BasePoco // <- not a MarshalByRefObject!
public MyInfo() ...
在 Init() 期间,子 AppDomain 实例化一个 POCO 对象,根据定义,该对象是不可编组的。我们还假设我们无法在这方面对其进行修改。
链接的答案表明,将其包装在 Container<T>
中(其本身是可编组的)应该允许将其传递回主 AppDomain。我理解这一点,因为它是真正被传递的 Container<MyInfo>
实例的代理。
我不明白的是主AppDomain如何通过容器的代理访问容器中的POCO实例。我在Container<T>
中看到了重载的隐式转换运算符,我知道它返回包含的 POCO 实例。但是该实例本身并没有被代理 - 它仍然在子 AppDomain 中!那么,这不应该中断吗?
这里到底发生了什么?
【问题讨论】:
最初的问题和容器概念对我来说没有多大意义。那里提到的Form类继承自MarshalByRefObject,所以使用容器是有心情的。此外,如果您使用容器的 Value peroperty,它的作用与您直接使用对象相同(即,如果对象不是 MarshalByRefObject,则序列化该对象)。 【参考方案1】:一旦容器返回存在于另一个 AppDomain 中的实例(无论是通过 Value 属性还是隐式转换运算符发生),该对象就会被编组。如果是 MarshalByRefObject,则会生成一个新的代理,以便您访问它。否则,该对象将被复制(按值编组、序列化)到当前应用程序域中。
该问题中显示的 Container 类唯一可以帮助解决的问题是,如果您想保留另一个不应编组的对象的代理。但是在这种情况下,您不能从代理所在的 AppDomain 访问 Value 属性或使用隐式转换运算符,因为这会导致容器中的对象被封送。尽管如此,您仍可以将容器用作与 Container 对象位于同一 AppDomain 中的对象的方法中的参数,因此基本上允许您保留对不可编组对象(不可序列化且不可 MarshalByRef 或类型)的引用在无法使用代理等加载到 AppDomain 的程序集中)并像“句柄”一样传递它。
【讨论】:
谢谢,卢塞罗!我也是这么想的。 :)以上是关于用于将 POCO 实例公开给其他 AppDomain 的通用容器 - 它是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章