【发布时间】:2011-07-13 03:10:48
【问题描述】:
我已经解决了一个令人生畏的难题。这是我的情况:
我正在使用插件框架构建应用程序。有一个所有插件都必须扩展的基本插件类。在同一个程序集中,我有一个辅助类,它将序列化和反序列化类。这是一个通用类,到处都在使用它。结构是这样的:
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]'"。经过大量研究I finally found why。它正在LoadNeither binding context 中加载。
当Foo 被加载(来自MyPlugin.dll)时,它位于LoadNeither 绑定上下文中,而包含用于类型转换的类型的程序集(在我的例子中是MyApp. dll) 在默认上下文中加载。因此,即使它们具有相同的名称,它们也不被视为同一类型。这样做是因为我使用的是Assembly.Load(byte[])。
问题
我该如何解决这个问题?我该怎么办,
- 加载程序集而不锁定文件,并且
- 提供正确的绑定上下文,以便我可以转换位于已加载程序集中的对象。
对不起,文字墙,只是想把所有相关信息都放在那里。
【问题讨论】:
标签: c# .net plugins assemblies assembly-loading