2

アンロードできる別の AppDomain 内のコンポーネント (サード パーティの dll に基づく) を分離する方法を探しています。私の計画は、コンポーネントとの通信にCreateInstanceAndUnwrapおよびMarshalByRefObjectベースのオブジェクトを使用することでした。

問題は、メイン アセンブリから派生したオブジェクトを使用するにMarshalByRefObjectは、コンポーネント dll を参照する必要があり、それを回避しようとしていることです。インターフェイスを介して分離できると思いました

class MyObject: MarshalByRefObject, IMyObject
{
}

CreateInstanceAndUnwrapしかし、から返されたオブジェクトをキャストすることはできませんIMyObject(実際にはプロキシであり、実際のオブジェクトではないと思いますか?)。

私は何かを見逃していますか、それともこれを行うことができず、唯一の答えは WCF ですか?

更新: 私が実際に抱えていた問題は、IMyObject が 2 回定義されたことでした。メイン アセンブリとコンポーネント アセンブリにファイルが含まれていました。このようにして、「透過プロキシをタイプにキャストできません」という例外が発生します。両方のアセンブリから参照するインターフェイス/クラス定義を 1 つだけ使用している場合、問題なく動作します (Will が提案したように、上記で説明したように)。

4

1 に答える 1

1

ええと、インターフェースはとにかくひどいです。

それを捨てて、MBRO から継承する抽象基本クラスを使用します。

public abstract class MyObject : MarshalByRefObject
{
    protected MyObject() : base() {}
    public abstract void LoadPluginAssemblyLol();
    public abstract void ExecuteSuperCollider();
}

それを境界を越えて引き戻し、プラグインをそのように制御します。また、型でイベントを公開しないことを忘れないでください (イベント サブスクライバーは、気付かないうちに境界を越えて引っ張られます)。おそらくメソッド引数のみを取り、プリミティブまたは厳密に制御された戻り値を持って、誤って終了しないようにする必要があります。メイン ドメインにロードされた dll。

もう 1 つの問題は、 ISponsor実装を介してプロキシされるオブジェクトの寿命を管理する必要があることです。それ以外の場合、ホスト ドメインのインスタンスは 10 分後に収集されます。

MyObject の使用に関しては、...

// 'class MyObjectImplementation : MyObject {...}' などの実装を想定

var type = typeof(MyObjectImplementation);
var newDomain = CreateNewAppDomainKthx();
var controller = newDomain
    .CreateInstanceAndUnwrap(
        type.Assembly.FullName, 
        type.FullName) as MyObjectImplementation;
controller.LoadPluginAssemblyLol();
controller.ExecuteSuperCollider();
于 2013-09-12T18:52:18.093 に答える