那么如何解决这个问题了?我觉得至少有两种方案:
(1)使用AppDomain。在一个新的AppDomain中加载插件,然后通过卸载这个AppDomain就可以干净地从服务系统中卸载该AppDomain中的插件Dll。这种方案的缺陷是需要管理众多的AppDomain(因为你有众多的功能服务),而且跨AppDomain的通信都是以Remoting的方式进行的,这将为我们的系统引入不少本不必要的麻烦。如果你有兴趣也可以尝试一下这种方案,而我更喜欢用第二种。
(2)在内存中复制插件Dll,然后加载内存中的Dll。这样,硬盘上的Dll就可以随意地被覆盖或删除了。以前我们是直接从硬盘加载插件Dll,就像这样:
Assembly asm = Assembly.LoadFrom(addinFilePath) ;
现在,我们需要转个弯: Assembly asm = null ;
//先将插件拷贝到内存缓冲
byte[] addinStream = null ;
if(FileHelper.ReadFileToBuff(addinFilePath ,out addinStream))
{
asm = Assembly.Load(addinStream) ; //加载内存中的Dll
}
//先将插件拷贝到内存缓冲
byte[] addinStream = null ;
if(FileHelper.ReadFileToBuff(addinFilePath ,out addinStream))
{
asm = Assembly.Load(addinStream) ; //加载内存中的Dll
}
这样就解决了插件的“动态替换”的问题。