Wintle·旧居

个人blog移至:http://www.wintle.cn,欢迎光临。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

黄天不负有心人,终于全身而退,哈哈

Posted on 2005-08-19 21:35  Wintle  阅读(2046)  评论(2编辑  收藏  举报

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,搞定。