13

別のアセンブリ (ビルド時には不明) から型を「動的」として読み込み、その型でメソッドを実行しようとしています。私の目標は、「プラグイン」を親アプリケーションから完全に切断して、共有コードや共通のインターフェイス タイプを必要としないようにすることです。インターフェースは、ロードされた型の予期されるメソッド シグネチャによって暗示されます。

これは機能します:

dynamic myObj = Assembly.Load("MyAssembly").CreateInstance("MyType");
myObj.Execute();

ただし、これにより、その型がすべての依存アセンブリと共に現在の AppDomain に読み込まれます。これを変更して、別の AppDomain で同じことを実行できるようにします。

これは機能しますが、dynamic キーワードを使用しません。Execute メソッドを呼び出すには、インスタンス化する明示的な型を知る必要があります。

var appDomain = AppDomain.CreateDomain(domainName, evidence, setup);
var myObj = appDomain.CreateInstanceAndUnwrap(assembly, type);
typeof(IMyInterface).InvokeMember("Execute",  BindingFlags.InvokeMethod, null, myObj);

これは本質的に私のターゲットケースであり、次のようなものを機能させようとしています:

dynamic myObj = ad.CreateInstanceAndUnwrap(assembly, type);
myObj.Execute();

「'System.MarshalByRefObject' には 'Execute' の定義が含まれていません」というメッセージが表示された RuntimeBinderException が発生し続けます。このメッセージは理にかなっています。'Execute' の定義が含まれていないことは確かですが、インスタンス化しようとしている型に実際に 'Execute' メソッドが含まれていることはわかっています。これが機能しないようにしている透過プロキシで何かが起こっていると思いますが、何がわからないのですか。

インスタンス化しようとしている実際のクラスは次のようになります。

[Serializable]
public class MyClass : MarshalByRefObject {
  public void Execute() {
    // do something
  }
}

また、共有インターフェイスでこれを試しました(私の主な目標ではありませんが、最初にこれを理解しようとしています)ので、次のようになります。

[Serializable]
public class MyClass : MarshalByRefObject, IPlugin {
  public void Execute() {
    // do something
  }
}

IPlugin は親アプリケーションで既知のタイプであり、プラグインはビルド時に適切な参照を持っていますが、これも機能していないようです。

この時点で、AppDomain の境界を越えて型を動的として読み込むことはできないと推測しています。

これを実際に機能させる方法はありますか?

4

1 に答える 1

5

leppie が示したように、返されるプロキシをラップするIDynamicMetaObjectProviderインターフェイスを実装する必要があります。その後、その上dynamicmake呼び出しを使用できます。

実装では、ラップされたプロキシを取得し、すべての呼び出しをクラスの静的ExecuteMessageメソッドに転送する必要があります。これにより、プロキシとインターフェイスの実装が取得されます。RemotingServicesIMethodCallMessage

IMethodCallMessageインターフェイスの実装は簡単ではないことに注意してください。また、戻り値とパラメーター (存在する場合) を正しく取得するには、IMethodReturnMessageインターフェイスの実装を適切に解釈する必要があります。refout

とはいえ、一般的には、クライアントとサーバーが想定するインターフェイスのみを含むアセンブリを提供することをお勧めします。サーバー側で何らかの方法でメソッドが変更された場合、クライアント側で が使用されていても、変更に対応するために呼び出しサイトを変更する必要がありますdynamic。少なくともこのインターフェースでは、実行時エラーよりも常に好まれるある種のコンパイル時チェックが得られます。

于 2012-06-26T20:34:14.473 に答える