私は手ごわい難問に立ち向かいました。これが私の状況です:
プラグインフレームワークを使用してアプリケーションを構築しています。すべてのプラグインが拡張する必要のある基本プラグインクラスがあります。同じ同じアセンブリ内に、クラスをシリアル化および逆シリアル化するヘルパークラスがあります。これはジェネリッククラスであり、あらゆる場所で使用されています。構造は次のようになります。
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バインディングコンテキストにロードされます。
がFoo
(MyPlugin.dllから)読み込まれると、LoadNeither
バインディングコンテキストにあり、型変換の型を含むアセンブリ(私の場合はMyApp.dll)が既定のコンテキストで読み込まれます。したがって、同じ名前であっても、同じタイプとは見なされません。私が使用しているので、これを行っていAssembly.Load(byte[])
ます。
質問
どうすればこれを回避できますか?どうやって、
- アセンブリをロードし、ファイルをロックしないでください。
- ロードされたアセンブリにあるオブジェクトをキャストできるように、適切なバインディングコンテキストを提供します。
テキストの壁で申し訳ありませんが、関連するすべての情報を入手したかっただけです。