Plugin 的插入和退出机制,都搞定啦。郁闷了二天了。
由于这个Plugin机制相对有点复杂(这个相对大概是针对网上能找到的那些plugin的demo来说的,),有类多重继承,有接口,还有接口的继承,也弄不明白,为什么,我就是不能成功地把dll给卸载下来,后来也只好采用AppDomain的ShadowCopyFiles方法,但一开始也不成功。。
OK,现在总结一下先。
这个Plugin机制,主要是依照codeproject上的一个例子:
http://www.codeproject.com/csharp/livecodedotnet.asp (动态编译)
动态编译的例子,很简单,也很成功。这个例子的思路很好:
在AppDomain里建立一个返回Interface的Factory,然后导入dll,返回接口,执行,然后AppDomain.UnLoad()掉。
这个例子可没有用ShadowCopyFiles 方法。
从这个例子得到的有价值信息有:
1、在导入的dll,在继承上,是有顺序的,Factory要返回的接口,必须排在继承接口的首位上。(大概谁的接口在先,这个dll最后就归谁,不知道了。文章里也没有说清楚。
原文如下:
An important hint if you extend the component model: Please be sure to specify the class interface inheritance list by placing the plug-in interfaces at the beginning:
public class YourPluginClass : MarshalByRefObject, IPlugInterface,
IYourLocalInterface
If you write the wrong order:
public class YourPluginClass : MarshalByRefObject, IYourLocalInterface,
IPlugInterface
your plugin-assembly will be attached to the primary domain and thus be locked.
2、如果你导入的dll里有AppDomains共享的东西(我也不知道是什么,大概我的程序就死在这个上面了..),则AppDomain.UnLoad( yourDomain )后,也不能清除和真正卸载这个dll,而且除了关闭整个应用程序外,别无他法。。(郁闷了)
于是我只好采用ShadowCopyFiles方式,找了很多文档,曾经把AppDomainSetup的属性设置了七八条之多,还是不行,更有甚者,看到msdn上有说对这个AppDomainSetup的文档不足,甚至有错之处...
好了,后来,无意中又是在CodeProject上看到一个demo,(CodeProject真是好哈,看起来,最能帮我解决问题的就是她啦)
http://www.codeproject.com/csharp/CodeCompilation.asp (这也是动态编译)
与上一个例子不同的是,他采用的是ShadowCopyFiles的方式,我试了一下,执行后,还是可以直接删除dll,这说明dll没有被lock住哈,OK,满足我的要求。但看代码也没有什么奇怪的地方啊。。为什么别的就不行?仔细一看,发现如下的区别:
AppDomainSetup ads = new AppDomainSetup();
ads.ShadowCopyFiles = "true";
AppDomain.CurrentDomain.SetShadowCopyFiles();
看到了没,人家可不是 ads.SetShadowCopyFiles();
OK,搞定。