我已经克服了一个令人生畏的难题。这是我的情况:
我正在使用插件框架构建应用程序。有一个基本插件类,所有插件都必须扩展。在同一个程序集中,我有一个帮助程序类,它将序列化和反序列化类。它是一个通用类,它遍布各处。结构是这样的:
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
绑定上下文中,而包含类型转换类型的程序集(在我的情况下,< em> MyApp.dll )在Default上下文中加载。因此即使它们具有相同的名称,它们也不被认为是相同的类型。这样做是因为我正在使用Assembly.Load(byte[])
。
我该如何解决这个问题?我怎么能,
对于文字墙感到抱歉,只是想获得所有相关信息。
答案 0 :(得分:6)
您是否尝试过shadow copying?
当您使用卷影复制时,.NET会将程序集复制到临时目录并从那里加载它(因此它是锁定的临时文件,而不是原始程序集) - 但所有绑定规则都基于原始文件位置。
答案 1 :(得分:2)
从我的头脑中只是一个想法:
如果有一个Plugin目录,用户可以将其插件插入其中。然后在您的应用程序中,您监视该文件夹并将程序集复制到bin或其他任何内容。 然后你以“正常”方式加载它们,这可能会锁定它们。
当用户删除新插件时,您将终止插件应用程序域并重新加载它们。
只是一个想法。