我已经解决了一个可怕的难题。这是我的情况:
我正在使用插件框架构建应用程序。有一个所有插件都必须扩展的基本插件类。在同一个程序集中,我有一个辅助类,它将序列化和反序列化类。这是一个通用类,到处都在使用它。结构是这样的:
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]'"
。经过大量研究,我终于找到了原因。它正在LoadNeither 绑定上下文中加载。
Foo
加载时(来自MyPlugin.dll)它位于LoadNeither
绑定上下文中,而包含用于类型转换的类型的程序集(在我的情况下为MyApp.dll)在默认上下文中加载。因此,即使它们具有相同的名称,它们也不被视为同一类型。这样做是因为我正在使用Assembly.Load(byte[])
.
问题
我怎样才能解决这个问题?我怎样才能,
- 加载程序集而不锁定文件,并且
- 提供正确的绑定上下文,以便我可以转换位于已加载程序集中的对象。
对不起,文字墙,只是想把所有相关信息都放在那里。