用于将 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&lt;T&gt; 中(其本身可编组的)应该允许将其传递回主 AppDomain。我理解这一点,因为它是真正被传递的 Container&lt;MyInfo&gt; 实例的代理。

我不明白的是主AppDomain如何通过容器的代理访问容器中的POCO实例。我在Container&lt;T&gt; 中看到了重载的隐式转换运算符,我知道它返回包含的 POCO 实例。但是该实例本身并没有被代理 - 它仍然在子 AppDomain 中!那么,这不应该中断吗?

这里到底发生了什么?

【问题讨论】:

最初的问题和容器概念对我来说没有多大意义。那里提到的Form类继承自MarshalByRefObject,所以使用容器是有心情的。此外,如果您使用容器的 Value peroperty,它的作用与您直接使用对象相同(即,如果对象不是 MarshalByRefObject,则序列化该对象)。 【参考方案1】:

一旦容器返回存在于另一个 AppDomain 中的实例(无论是通过 Value 属性还是隐式转换运算符发生),该对象就会被编组。如果是 MarshalByRefObject,则会生成一个新的代理,以便您访问它。否则,该对象将被复制(按值编组、序列化)到当前应用程序域中。

该问题中显示的 Container 类唯一可以帮助解决的问题是,如果您想保留另一个不应编组的对象的代理。但是在这种情况下,您不能从代理所在的 AppDomain 访问 Value 属性或使用隐式转换运算符,因为这会导致容器中的对象被封送。尽管如此,您仍可以将容器用作与 Container 对象位于同一 AppDomain 中的对象的方法中的参数,因此基本上允许您保留对不可编组对象(不可序列化且不可 MarshalByRef 或类型)的引用在无法使用代理等加载到 AppDomain 的程序集中)并像“句柄”一样传递它。

【讨论】:

谢谢,卢塞罗!我也是这么想的。 :)

以上是关于用于将 POCO 实例公开给其他 AppDomain 的通用容器 - 它是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章

将受保护的 Objective-C 实例变量公开给子类

如何使用 cython 将 python 类公开给 c++

POCO 模型和计算字段

将公共属性和方法公开给 Main Activity 的片段是不是是一种不好的形式?

如何使用Poco :: ZIP压缩/解压缩zip文件

我在 Azure 中执行了“公开 API”,但无法将该范围的令牌提供给客户端程序