POCOインスタンスを他のAppDomainに公開するための汎用コンテナー-どのように機能しますか?
-
03-07-2019 - |
質問
別のSOスレッドからのこれの回答に興味があり、誰かがコンセプトに光を当てるのを手伝ってくれることを望んでいた。
プライマリAppDomainと、プライマリ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.
}
}
子AppDomain:
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インスタンスにアクセスする方法です。オーバーロードされた暗黙のキャスト演算子が<=>にあり、含まれているPOCOインスタンスを返すことを理解しています。しかし、そのインスタンス自体はプロキシされません-それはまだ子AppDomainにあります!それで、これは壊れてはいけませんか?
ここで実際に何が起こっているのですか?
解決
コンテナが他のAppDomainに存在するインスタンスを返すとすぐに(これがValueプロパティまたは暗黙の変換演算子を介して発生するかどうかに関係なく)、オブジェクトはマーシャリングされます。 MarshalByRefObjectの場合、アクセスできるように新しいプロキシが生成されます。それ以外の場合、オブジェクトは現在のアプリケーションドメインにコピーされます(値によって整列化され、シリアル化されます)。
この質問に示されているContainerクラスが役立つのは、マーシャリングすべきではない別のオブジェクトへのプロキシを保持する場合だけです。ただし、この場合、Valueプロパティにアクセスしたり、プロキシが存在するAppDomainから暗黙的な変換演算子を使用したりしないでください。コンテナ内のオブジェクトがマーシャリングされるためです。それでも、コンテナをコンテナオブジェクトと同じAppDomainに存在するオブジェクトのメソッドへの引数として使用することができます。したがって、基本的に、マーシャリング不可能なオブジェクト(MarshalByRefではなく、またはプロキシなどを使用してAppDomainにロードできないアセンブリで)、<!> quot; handle <!> quot;のように渡します。