7

私は手ごわい難問に立ち向かいました。これが私の状況です:

プラグインフレームワークを使用してアプリケーションを構築しています。すべてのプラグインが拡張する必要のある基本プラグインクラスがあります。同じ同じアセンブリ内に、クラスをシリアル化および逆シリアル化するヘルパークラスがあります。これはジェネリッククラスであり、あらゆる場所で使用されています。構造は次のようになります。

MyApp.dll
|_ App.cs
|_ HelperCollection.cs
|_ PluginBase.cs

MyPlugin.dll
|_MyPlugin.cs (this extends PluginBase)
|_Foo.cs

問題

私の問題は、アセンブリのロードとファイルのロックです。アプリの要件は、プラグインをいつでも上書きできることです。その場合は、リロードする必要があります。ロックされないように(つまり、アプリの実行中に上書きしたり吹き飛ばしたりできるように)アセンブリをロードするのが最善の方法のようです。

byte[] readAllBytes = File.ReadAllBytes("MyPlugin.dll");
Assembly assembly = Assembly.Load(readAllBytes);

プラグインアセンブリのロードは問題なく機能します。問題はありません。プラグインアセンブリにあるMyPlugin.cs内から、を使用HelperCollectionして逆シリアル化を実行しようとすると、例外が発生します。例は次のようになります。

// HelperCollection uses XmlSerializer under the covers
List<Foo> settingCollection = HelperCollection<Foo>.Deserialize("mysettings.xml");

それは爆破し、InvalidCastExceptionそれがだということわざを投げてい"Unable to cast object of type 'List[Foo]' to 'List[Foo]'"ます。多くの調査の後、私はついにその理由を見つけましたLoadNetherバインディングコンテキストにロードされます。

FooMyPlugin.dllから)読み込まれると、LoadNeitherバインディングコンテキストにあり、型変換の型を含むアセンブリ(私の場合はMyApp.dll)が既定のコンテキストで読み込まれます。したがって、同じ名前であっても、同じタイプとは見なされません。私が使用しているので、これを行っていAssembly.Load(byte[])ます。

質問

どうすればこれを回避できますか?どうやって、

  1. アセンブリをロードし、ファイルをロックしないでください。
  2. ロードされたアセンブリにあるオブジェクトをキャストできるように、適切なバインディングコンテキストを提供します。

テキストの壁で申し訳ありませんが、関連するすべての情報を入手したかっただけです。

4

2 に答える 2

6

シャドウコピーを試しましたか?

シャドウコピーを使用している場合、.NETはアセンブリを一時ディレクトリにコピーしてそこからロードします(つまり、元のアセンブリではなく、ロックされているのは一時ファイルです)。ただし、すべてのバインドルールは元のファイルの場所に基づいています。 。

于 2011-03-11T00:01:04.580 に答える
2

私の頭のてっぺんからのアイデア:

ユーザーがプラグインをドロップできるプラグインディレクトリがあるのはどうですか。次に、アプリケーションで、そのフォルダーを監視し、アセンブリをビンなどにコピーします。次に、それらを「通常の」方法でロードします。これにより、それらがロックされる可能性があります。

ユーザーが新しいプラグインをドロップすると、プラグインアプリドメインを強制終了してリロードします。

ただのアイデア。

于 2011-03-10T23:44:12.680 に答える