<?xml version="1.0" encoding="UTF-8"?>
  <feed xmlns="http://www.w3.org/2005/Atom">
  <title type="html"><![CDATA[Cooldog's BLOG 酷狗的窝]]></title>
  <subtitle type="html"><![CDATA[君看一叶舟，出没风波里]]></subtitle>
  <id>http://www.xiaozhou.net/cooldog/</id>
  <link rel="alternate" type="text/html" href="http://www.xiaozhou.net/cooldog/" /> 
  <link rel="self" type="application/atom+xml" href="http://www.xiaozhou.net/cooldog/atom.asp" /> 
  <generator uri="http://www.pjhome.net/" version="2.8">PJBlog3</generator> 
  <updated>2008-07-31T00:14:20+08:00</updated>

  <entry>
	  <title type="html"><![CDATA[Blog up&#100;ated]]></title>
	  <author>
		 <name>cooldog</name>
		 <uri>http://www.xiaozhou.net/cooldog/</uri>
		 <email>yexiaozhou2003[AT]hotmail.com</email>
	  </author>
	  <category term="" scheme="http://www.xiaozhou.net/cooldog/default.asp?cateID=17" label="随笔" /> 
	  <updated>2008-07-31T00:14:20+08:00</updated>
	  <published>2008-07-31T00:14:20+08:00</published>
		  <summary type="html"><![CDATA[<p>今天上网才发现，原来PJBlog有更新了。去作者主页看了看，才知道原来发布了一个V2.8的里程碑版本，后续还有一系列更新。于是我立马去把我的blog升级成PJBlog3了，呵呵。总体看来作者这次改动很大，尤其是blog后台界面，美化了不少的地方，还增加全静态化功能&nbsp;，提高了访问的性能。<img alt="" src="http://www.xiaozhou.net/cooldog//cooldog/fckeditor/editor/images/smiley/qq2007/79.gif" />&nbsp; 文章表情也更新了很多。看来作者是下了大功夫的，不更新太对不起作者的劳动成果了 <img alt="" src="http://www.xiaozhou.net/cooldog//cooldog/fckeditor/editor/images/smiley/qq2007/20.gif" />&nbsp;&nbsp; 希望这个版本不会有太多的bug。<br />
打完收工&hellip;&hellip;<img alt="" src="http://www.xiaozhou.net/cooldog//cooldog/fckeditor/editor/images/smiley/qq2007/47.gif" /><img alt="" src="http://www.xiaozhou.net/cooldog//cooldog/fckeditor/editor/images/smiley/qq2007/47.gif" />&nbsp;<img alt="" src="http://www.xiaozhou.net/cooldog//cooldog/fckeditor/editor/images/smiley/qq2007/47.gif" /><br />
<img alt="" src="http://www.xiaozhou.net/cooldog//cooldog/fckeditor/editor/images/smiley/qq2007/8.gif" />去了&hellip;&hellip;</p>]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.xiaozhou.net/cooldog/article.asp?id=194" /> 
	  <id>http://www.xiaozhou.net/cooldog/default.asp?id=194</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[Linq to SQL 的更新冲突与管理]]></title>
	  <author>
		 <name>cooldog</name>
		 <uri>http://www.xiaozhou.net/cooldog/</uri>
		 <email>yexiaozhou2003[AT]hotmail.com</email>
	  </author>
	  <category term="" scheme="http://www.xiaozhou.net/cooldog/default.asp?cateID=22" label=".NET开发" /> 
	  <updated>2008-07-03T01:37:00+08:00</updated>
	  <published>2008-07-03T01:37:00+08:00</published>
		  <summary type="html"><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;前段时间工作中的一个新需求，有机会用到了Linq to SQL。使用后的第一感觉，就是方便很多，也为整个项目节约了一大把的开发时间，甚至代码量也少了很多。不过在程序的实际运行中，始终会遇到一些莫名其妙的异常，最令人不解的，就是“System.Data.Linq.ChangeConflictException: Row not found o&#114; changed.” 。当初凭自己和同事的判断，可能是数据库的数据异常所导致，后来发觉这个异常出现得越来越频繁，于是上MSDN查了查，原来是Linq中一个常见的问题：更新冲突。<br/>&nbsp;&nbsp; 这个词说起来比较玄乎，其实再平常不过了。下面可以通过一个简单的例子，来重现这个异常。<br/>&nbsp;&nbsp; 建立一个普通的测试表：LinqTest(如图)<br/><br/>&nbsp;&nbsp; <img src="http://www.xiaozhou.net/cooldog/pics/linq1.jpg" border="0" alt=""/> <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; 在测试表中，插入一条测试数据(如图)<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;<img src="http://www.xiaozhou.net/cooldog/pics/linq2.jpg" border="0" alt=""/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; 测试代码如下：<br/><br/>&nbsp;&nbsp; <div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.xiaozhou.net/cooldog/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>namespace LinqTest<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;class Program<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static void Main(string[] args)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TestDataContext db = new TestDataContext();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;db.Log = Console.Out;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var result = from p in db.LinqTests<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wh&#101;re p.ID == 1<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sel&#101;ct p;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var info = result.FirstOrDefault();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(info != null)&nbsp;&nbsp;&nbsp;&nbsp; //插入断点<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;info.Age = 25;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;db.SubmitChanges();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.ReadLine();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>}<br/>&nbsp;&nbsp;&nbsp;&nbsp;</div></div><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;在测试代码中，将DataContext的日志定向到Console的输出部分，这样方便我们观察Linq实际执行的SQL语句是什么。重现的时候，我们需要在注释的地方，插入断点进行测试。对于示例中的代码，在正常情况下，是不会有错误的。执行过后，我们可以在Console的输出中，看到实际执行的SQL语句(如图)<br/><br/><img src="http://www.xiaozhou.net/cooldog/pics/linq4.jpg" border="0" alt=""/><br/><br/>&nbsp;&nbsp; 再进行第二次调试，首先，恢复Age的数据到以前的样子。下面我们运行到断点处，然后偷偷去SQL Server Management Studio中，手动修改数据，将原始数据中的Age，由24，改为22。然后回到VS2008的IDE，按F5继续运行程序，这个时候，你会发现异常出现了(如图)<br/><br/><img src="http://www.xiaozhou.net/cooldog/pics/linq3.jpg" border="0" alt=""/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;再回到Console的输出，查看，执行的SQL语句和刚才的一样。这就是问题的所在，在正常运行状态下，Linq在运行时，会把数据库的数据缓存到实体对象中，这是一种理想化的情况，并且在更新时，Linq会默认把除更新字段外的所有字段，作为Up&#100;ate语句中的Wh&#101;re条件。但是，如果此时有另外的程序，在访问数据库，并修改数据库数据的时候，比如刚才把Age改为22。此时Linq缓存起来的数据和实际数据库中的数据产生了不一致的情况。Linq此时仍然把被修改过的字段，作为Up&#100;ate的Wh&#101;re条件，但是数据库中Age早就被我们改过了，不再是25，Wh&#101;re条件始终匹配不到原有的数据。这时，就会抛出所谓的：“System.Data.Linq.ChangeConflictException: Row not found o&#114; changed.”异常。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;产生此异常，主要是Linq缓存数据和实际数据库数据不一致的情况造成。解决次问题的情况，主要有几种：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;1.比较简单的方法，不使用Linq提供的SubmitChanges()方式提交更改，而直接执行SQL语句，例如：<br/>&nbsp;&nbsp;&nbsp;&nbsp; db.ExecuteCommand(&#34;Up&#100;ate [dbo].[LinqTest] SET Age=25 Wh&#101;re ID = @p0&#34;, 1);<br/>&nbsp;&nbsp;&nbsp;&nbsp;这样虽然比较方便，但是感觉又回到了直接写SQL的时代，毕竟Linq to SQL的目的，就是为了让我们看不见SQL，避免写复杂的SQL语句，而直接操作实体对象，这样也可以避免程序可读性差、不便于维护。所以除非万不得已，还是不太推荐使用此方法。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;2.参考MSDN的资料，采用Linq提供的解决更新冲突的方法，在异常中捕获冲突，然后手动解决冲突：<br/> <div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.xiaozhou.net/cooldog/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">&nbsp;&nbsp; <br/>try<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;db.SubmitChanges(System.Data.Linq.ConflictMode.ContinueOnConflict);<br/>}<br/>catch (System.Data.Linq.ChangeConflictException ex)<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;foreach (System.Data.Linq.ObjectChangeConflict occ in db.ChangeConflicts)<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //以下是解决冲突的三种方法，选一种即可<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 使用当前数据库中的值，覆盖Linq缓存中实体对象的值<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;occ.Resolve(System.Data.Linq.RefreshMode.OverwriteCurrentValues);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 使用Linq缓存中实体对象的值，覆盖当前数据库中的值<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;occ.Resolve(System.Data.Linq.RefreshMode.KeepCurrentValues);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 只更新实体对象中改变的字段的值，其他的保留不变<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;occ.Resolve(System.Data.Linq.RefreshMode.KeepChanges);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;// 这个地方要注意，Catch方法中，我们前面只是指明了怎样来解决冲突，这个地方还需要再次提交更新，这样的话，值&nbsp;&nbsp;&nbsp;&nbsp;//才会提交到数据库。<br/>&nbsp;&nbsp;&nbsp;&nbsp;db.SubmitChanges();<br/>}<br/><br/></div></div><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;3. 这个方法也比较简单，也即MSDN中所说的Pessimistic Concurrency Control&nbsp;&nbsp;。 我们可以来设定哪些字段需要放入Wh&#101;re条件，哪些字段不需要，这样就可以控制更新时候的条件匹配尺度。具体做法，就是在Linq to SQL Designer中，把一些字段的Up&#100;ateCheck属性设置为Never，这样，这些字段在更新的时候，就不会再出现在Wh&#101;re条件中了。其实比较推荐的做法，就是在表中设立主键，因为更新的时候，只要把主键作为Wh&#101;re条件，就可以单独的确立一行数据了。把除主键外的字段属性中Up&#100;ateCheck设置为Never即可。<br/><br/><br/>关于Linq to SQL中如何管理更改冲突的更多资料，可以在MSDN找到<br/><a href="http://msdn.microsoft.com/zh-cn/library/bb399389.aspx" target="_blank" rel="external">http://msdn.microsoft.com/zh-cn/library/bb399389.aspx</a>]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.xiaozhou.net/cooldog/article.asp?id=193" /> 
	  <id>http://www.xiaozhou.net/cooldog/default.asp?id=193</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[救救绵竹！]]></title>
	  <author>
		 <name>cooldog</name>
		 <uri>http://www.xiaozhou.net/cooldog/</uri>
		 <email>yexiaozhou2003[AT]hotmail.com</email>
	  </author>
	  <category term="" scheme="http://www.xiaozhou.net/cooldog/default.asp?cateID=17" label="随笔" /> 
	  <updated>2008-05-16T16:59:14+08:00</updated>
	  <published>2008-05-16T16:59:14+08:00</published>
		  <summary type="html"><![CDATA[高洪珠特注：我将此文发到我的天涯和新浪博客上，发到天涯杂谈上。泣请大家尽量将此文转发到各个网站上，各个论坛上，转到你们的博客上，我谢谢你了，绵竹的灾民谢谢你了，绵竹谢谢你了！！！！！！！！<br/><br/>　　我以一个难民的身份逃到成都，在亲戚家里住着。其实一个很大的原因就是为了上网，作为一个自愿者也好，作为一个义工也好，把灾区绵竹最真实的情况发出去。让更多的人知道，让上级部门知道，希望绵竹能尽快得到有效的救助。<br/>　　我离开绵竹之前，绵竹城区的十万左右的难民住在户外，天下着大雨。避雨的东西作用不大，有些人干脆就没有。余震不断。人都变成神经质了，风吹草动都以为是地震，真正震起来的时候反而麻木了。<br/>　　城区的难民完全在自力更生，在自救。政府和部队都抽不出手来管城里的人，因为山区和农村的灾情更加严重。拉屎拉尿也没有地方，这样下去，会造成很恶劣的卫生情况，甚而导致急病的发生。<br/>　　最佳救助时间正在过去，甚至被浪费。<br/><br/>　　应该说，绵竹和德阳电视台向上面和全国人民反映绵竹灾情的力度很不够。你们的报道怎么可以还是站在领导的角度来表扬他们指挥有方什么的呢？给外人的感觉是绵竹的灾不重，误导了外地人和更上级的领导；应该多报些真实的灾情呀！<br/>　　在成都看电视的时候，很多都在说汶川，北川，其实绵竹的情况一点也不比那些地方好，甚至更加严重！<br/>　　我不知道绵竹报灾的时候是不是尽量往小里报，难道是习惯了吗？<br/><br/>　　临近山区的乡下民房几乎全垮了，不少人被埋，凶多吉少。救助效果不好，特别是头一两天，由于缺乏这方面的常识和经验，使很多难民失去了生还的可能。而外地的求援人员又没有到位。那么大一个东汽厂，头一天多居然只有自救！全靠温总理去了，援救的力度才得以加大，可是人命关天，拖不起啊！<br/><br/>　　山区非常严重。房屋垮塌，山体下滑，很多人死了。几个山区乡镇通讯和交通瘫痪，根本没有消息。<br/>　　遵道镇政府垮了，工作人员被活埋，死伤严重。<br/>　　九龙镇的街道也垮了。<br/>　　马尾的街也垮了。<br/>　　吉祥寺垮了，众僧和信众被埋。<br/>　　汉旺镇政府垮了，街道垮了。<br/>　　深山中的金花镇垮了。伤亡惨重。<br/>　　深山中的天池乡政府垮塌，两边的山把房子埋了。<br/>　　深山中的清平乡垮了。<br/>　　国家大型企业东方汽轮机厂若干分厂垮了，伤亡惨重！<br/>　　死亡无数！<br/><br/>　　学校成了重灾区。<br/>　　东汽中学当时正在上课，楼垮了，很多师生被埋，救活者极少，头天，很多自愿者看到听到活人却无力救活。东汽技校（汉旺校区）也垮了。<br/>　　九龙幼儿园的孩子正在午睡，楼垮了，８０多名孩子被埋，头天救了二十来个出来，救出来的活着的也很少。<br/>　　马尾学校。<br/>　　九龙学校。<br/>　　遵道学校。<br/>　　五福学校。<br/>　　天池学校。<br/>　　金花学校。<br/>　　天池学校。<br/>　　清平学校。<br/>　　我边流泪边打下这些学校的名字。那里的太多的师生啊！<br/>　　死亡和失踪的数字无法准确统计。<br/><br/>　　清平磷矿垮塌得非常厉害。<br/>　　其它的磷矿，煤矿我还不知道，但肯定不敢想像！<br/><br/>　　绵竹火葬厂堆了很多尸体，又无法烧。如果再不处理，就会引发瘟疫，希望有关部门采取断然措施，就地埋葬。甚至完全可以使用万人坑的形式，大灾之际非常时期，救活人要紧！！这件事情拖不得了！腐烂的气味已经开始传递了。周围一两里的人都只能戴着口罩来防止那难闻的味道，可是防得了吗？<br/>　　希望相关部门立即组织人力深埋尸体，同时做一些必要的消毒处理<br/><br/><br/>　　由于山体滑坡，堵了水路，如果水越积越多，再遇大雨暴雨的话，随时都可能引起山洪爆发，如果这样的话，后果将更加无法想像！<br/><br/>　　绵竹水电气全部中断，衣食住行都成了问题。食品和药品告急！<br/>　　十三号就有人在哄抬物价了，卤肉卖五十五一斤了。鸡蛋卖两块钱一只了。这个现象也应该制止。<br/>　　关键是应该尽快运物资去了！<br/>　　救救绵竹，救救绵竹！<br/><br/><br/>————————————————————————————<br/>下面是绵竹籍的北京大学大四学生谢佳秋提供的信息，大家相互转告。<br/><br/>随性随缘 评论日期：2008-5-15 18:32 <br/>　　　　 这是德阳的一个捐款渠道，你把他贴到你博客正文吧。已经获得证实了。<br/>　　　　 德阳驻京办捐助热线：01068002582，捐助账户名：德阳市人民政府驻北京联络处，账号：087507120100330004291，开户行：中国光大银行北京西城支行。 <br/>　　————————————————————————————————<br/>]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.xiaozhou.net/cooldog/article.asp?id=192" /> 
	  <id>http://www.xiaozhou.net/cooldog/default.asp?id=192</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[Dynamic Plugins Manager (五) Plugins Manager 源码下载 ]]></title>
	  <author>
		 <name>cooldog</name>
		 <uri>http://www.xiaozhou.net/cooldog/</uri>
		 <email>yexiaozhou2003[AT]hotmail.com</email>
	  </author>
	  <category term="" scheme="http://www.xiaozhou.net/cooldog/default.asp?cateID=16" label="我的拙作" /> 
	  <updated>2008-04-01T23:17:44+08:00</updated>
	  <published>2008-04-01T23:17:44+08:00</published>
		  <summary type="html"><![CDATA[今天和同事一起把Plugins Manager放在了google code上面。大家可以从下面的地址获取所有的源码了。<br/><br/><a href="http://code.google.com/p/dynamic-plugins-manager/" target="_blank" rel="external">http://code.google.com/p/dynamic-plugins-manager/</a>]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.xiaozhou.net/cooldog/article.asp?id=191" /> 
	  <id>http://www.xiaozhou.net/cooldog/default.asp?id=191</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[ Dynamic Plugins Manager (四) 插件及Demo源码下载]]></title>
	  <author>
		 <name>cooldog</name>
		 <uri>http://www.xiaozhou.net/cooldog/</uri>
		 <email>yexiaozhou2003[AT]hotmail.com</email>
	  </author>
	  <category term="" scheme="http://www.xiaozhou.net/cooldog/default.asp?cateID=16" label="我的拙作" /> 
	  <updated>2008-03-29T16:12:16+08:00</updated>
	  <published>2008-03-29T16:12:16+08:00</published>
		  <summary type="html"><![CDATA[&nbsp;&nbsp; 这里提供了插件的Demo程序，和编译好的Plugin Manager下载。<br/>&nbsp;&nbsp; Plugin Manager的代码待整理后放上来。 <img src="http://www.xiaozhou.net/cooldog/images/smilies/icon_cool.gif" border="0" style="margin:0px 0px -2px 0px" alt=""/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;开发运行环境：<br/>&nbsp;&nbsp; Windows Vista Ultimate<br/>&nbsp;&nbsp;&nbsp;&nbsp; .NET Framework 3.5<br/>&nbsp;&nbsp;&nbsp;&nbsp;Microsoft Visual Studio 2008<br/><br/>&nbsp;&nbsp; <img src="http://www.xiaozhou.net/cooldog/images/download.gif" alt="只允许会员下载" style="margin:0px 2px -4px 0px"/> 该文件只允许会员下载! <a href="http://www.xiaozhou.net/cooldog/login.asp">登录</a> | <a href="http://www.xiaozhou.net/cooldog/register.asp">注册</a><br/>]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.xiaozhou.net/cooldog/article.asp?id=190" /> 
	  <id>http://www.xiaozhou.net/cooldog/default.asp?id=190</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[Dynamic Plugins Manager (三) Demo]]></title>
	  <author>
		 <name>cooldog</name>
		 <uri>http://www.xiaozhou.net/cooldog/</uri>
		 <email>yexiaozhou2003[AT]hotmail.com</email>
	  </author>
	  <category term="" scheme="http://www.xiaozhou.net/cooldog/default.asp?cateID=16" label="我的拙作" /> 
	  <updated>2008-03-29T15:58:23+08:00</updated>
	  <published>2008-03-29T15:58:23+08:00</published>
		  <summary type="html"><![CDATA[&nbsp;&nbsp;下面来演示一下Plugins Manager，先看看我们事先做好的Interface和两个具体实现的插件.<br/><br/>&nbsp;&nbsp; Interface，接口定义：<br/>&nbsp;&nbsp;<div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.xiaozhou.net/cooldog/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>using System;<br/>using System.Collections.Generic;<br/>using System.Linq;<br/>using System.Text;<br/><br/>namespace Component<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;public interface IComponent<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string Invoke();<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/>&nbsp;&nbsp; </div></div><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;整个接口，只声明了一个Invoke方法，这也是具体的插件必须实现的一个方法。<br/><br/>&nbsp;&nbsp; 第一个插件类 class1.cs<br/>&nbsp;&nbsp;&nbsp;&nbsp;<div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.xiaozhou.net/cooldog/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>&nbsp;&nbsp;&nbsp;&nbsp;namespace Component<br/>{<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;public class Class1 : MarshalByRefObject,IComponent<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string message = string.Empty;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int number;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;float number2;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public Class1(string input, int num)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;message = input;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;number = num;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;number2 = 0;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public Class1(int num1, float num2)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;message = &#34;none&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;number = num1;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;number2 = num2;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public string Invoke()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return &#34;This is TestLibrary. member---message:&#34; + message + &#34;number:&#34; + number.ToString() + &#34;number2:&#34; +number2.ToString();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;</div></div><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;第二个插件类 class2.cs<br/>&nbsp;&nbsp;&nbsp;&nbsp;<div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.xiaozhou.net/cooldog/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>namespace Component<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;public class Class2 : MarshalByRefObject,IComponent<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public Class2()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public string Invoke()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return &#34;This is TestLibrary2 without construct param&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;</div></div><br/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;这里我们看到区别，第一个插件，需要构造函数，第二个插件不需要构造函数，所以在配置文件中，第二个插件可以关闭掉ConstructParam这个节点。<br/><br/>&nbsp;&nbsp; 下面我们将Class1.cs编译好，放到插件目录中，改名为TestLibrary.dll，将Class2.cs直接改名为TestLibrary2.cs，放到插件目录中。<br/>&nbsp;&nbsp; 演示的目的：插件1需要在加载时，构造初始化函数，而插件2不需要。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 插件1，是已经编译好的dll，不需要实时编译，但是插件2需要。<br/><br/>&nbsp;&nbsp; 下面是测试的截图<br/><br/>&nbsp;&nbsp; 1.插件目录，一个放入编译好的dll，一个放入.cs源码<br/>&nbsp;&nbsp; <br/><img src="http://www.xiaozhou.net/cooldog/pics/PluginManager/demo1.jpg" border="0" alt=""/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; 2.启动测试程序，看到2个插件都已经被加载<br/><br/><img src="http://www.xiaozhou.net/cooldog/pics/PluginManager/demo2.jpg" border="0" alt=""/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; 3.此时，再查看插件的目录，我们会看到Plugin Manager为我们编译，并生成的插件2的dll<br/><br/><img src="http://www.xiaozhou.net/cooldog/pics/PluginManager/demo3.jpg" border="0" alt=""/><br/><br/><br/>&nbsp;&nbsp; 4.查看插件的日志记录<br/><br/><img src="http://www.xiaozhou.net/cooldog/pics/PluginManager/demo4.jpg" border="0" alt=""/><br/><br/>&nbsp;&nbsp; 5.插件的调用<br/>&nbsp;&nbsp; 选中TestLibrary,点击Invoke按钮：<br/><br/><img src="http://www.xiaozhou.net/cooldog/pics/PluginManager/demo5.jpg" border="0" alt=""/><br/><br/>&nbsp;&nbsp;选中TestLibrary2,点击Invoke按钮：<br/><br/><img src="http://www.xiaozhou.net/cooldog/pics/PluginManager/demo6.jpg" border="0" alt=""/><br/><br/>&nbsp;&nbsp; 6.插件的动态卸载和发布<br/>&nbsp;&nbsp;&nbsp;&nbsp; a.动态卸载，可以直接使用Plugins Manager的UnloadPluginByName直接通过程序调用卸载。也可以手动打开插件的配置文件，将EnablePlugin设置为False<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b.动态发布，直接在插件目录中，建立一个新的子目录，然后将插件的dll和xml配置文件直接拷入即可<br/>&nbsp;&nbsp;&nbsp;&nbsp; 关于第6点，这些功能的演示，截图比较麻烦，大家可以直接使用测试程序测试即可。<br/>]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.xiaozhou.net/cooldog/article.asp?id=189" /> 
	  <id>http://www.xiaozhou.net/cooldog/default.asp?id=189</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[Dynamic Plugins Manager (二) 配置及实现分析]]></title>
	  <author>
		 <name>cooldog</name>
		 <uri>http://www.xiaozhou.net/cooldog/</uri>
		 <email>yexiaozhou2003[AT]hotmail.com</email>
	  </author>
	  <category term="" scheme="http://www.xiaozhou.net/cooldog/default.asp?cateID=16" label="我的拙作" /> 
	  <updated>2008-03-29T15:24:58+08:00</updated>
	  <published>2008-03-29T15:24:58+08:00</published>
		  <summary type="html"><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;整个Plugins Manager是一个基于dll的程序集，开发平台，基于VS2008和.NET 3.5 Framework。为何要用.NET 3.5呢？没别的原因，只要是为了尝试一下Linq to XML  <img src="http://www.xiaozhou.net/cooldog/images/smilies/icon_cool.gif" border="0" style="margin:0px 0px -2px 0px" alt=""/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;使用改组件，需要在应用程序中，添加引用。另外，还需要在应用程序中，建立相关的配置项：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.xiaozhou.net/cooldog/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>&lt;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34; ?&gt;<br/>&lt;configuration&gt;<br/>&nbsp;&nbsp;&lt;appSettings&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;add key=&#34;PluginsPath&#34; value=&#34;D:\MyCode\C# Projects\DynamicPlugInsApp\DynamicPlugInsApp\bin\Debug\Plugins&#34;/&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;add key=&#34;LogPath&#34; value=&#34;D:\MyCode\C# Projects\DynamicPlugInsApp\DynamicPlugInsApp\bin\Debug\Log&#34;/&gt;<br/>&nbsp;&nbsp;&lt;/appSettings&gt;<br/>&lt;/configuration&gt;<br/></div></div><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;PluginsPath是插件的主目录，里面通过子目录的方式，存放不同的插件。Plugins Manager在启动的时候，会遍历插件主目录，并搜寻可加载的插件。<br/>&nbsp;&nbsp; LogPath是插件的日志目录，里面的日志文件，会详细记载插件管理器当前的运行情况。<br/><br/>&nbsp;&nbsp; 另外，在Plugins Manager中，区别不同的插件，是根据不同的插件名称来决定的，这取决于插件dll的命名。<br/>&nbsp;&nbsp; 对于不同的插件，Plugins Manager也提供不同的特性配置文件。配置文件是.xml文件，命名需要和插件dll相一致。<br/>&nbsp;&nbsp; 下面是一个配置文件的示例：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.xiaozhou.net/cooldog/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>&lt;?xml version=&#34;1.0&#34; encoding=&#34;utf-8&#34; ?&gt;<br/>&lt;Plugin&gt;<br/>&nbsp;&nbsp;&lt;TypeName&gt;Component.Class1&lt;/TypeName&gt;<br/>&nbsp;&nbsp;&lt;EnablePlugin&gt;True&lt;/EnablePlugin&gt;<br/>&nbsp;&nbsp;&lt;ConstructParams&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp; &lt;Param type=&#34;string&#34; value=&#34;msadc&#34; /&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp; &lt;Param type=&#34;int&#34; value=&#34;12&#34; /&gt;<br/>&nbsp;&nbsp;&lt;/ConstructParams&gt;<br/>&nbsp;&nbsp;&lt;ReferenceList&gt;<br/>&nbsp;&nbsp; &lt;Reference&gt;D:\MyCode\C# Projects\DynamicPlugInsApp\ITestInterface\bin\Debug\ITestInterface.dll&lt;/Reference&gt;<br/>&nbsp;&nbsp;&lt;/ReferenceList&gt;<br/>&lt;/Plugin&gt;<br/></div></div><br/><br/>&nbsp;&nbsp; TypeName:插件的类名，和具体的插件命名空间和类名有关，Plugins Manager根据配置文件提供此相关信息，通过.NET的反射技术，生成具体的插件Instance<br/>&nbsp;&nbsp; EnablePlugin:插件开关，True表示当前插件可用，False表示阻止Plugins Manager加载此插件。该开关可以在Plugins Manager运行前设定，也可以在Plugins Manager运行时动态更改。Plugins Manager会检测配置文件变化，并留意EnablePlugin开关，以决定是否动态加载或者卸载该插件。<br/>&nbsp;&nbsp;ConstructParams:此节点，及其子节点，用以读取插件是否需要在运行时初始化构造函数。子节点用以描述构造函数中的参数，以及类型，和初始化的值。构造初始化函数，也是在.NET的反射中实现。<span style="color:Red">这里要注意，节点顺序和构造函数参数顺序有关</span>。如果插件不需要构造函数，可以关闭此节点。<br/>&nbsp;&nbsp;ReferenceList:此节点用以需要动态编译的插件，如果插件代码中还引用了其他的程序集，需要在此进行描述。<br/><br/>&nbsp;&nbsp;此外，插件还提供了事件通知功能，供应用程序进行响应和处理，实现的事件类型有以下几种：<br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;<div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.xiaozhou.net/cooldog/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>&nbsp;&nbsp;&nbsp;&nbsp;public enum PluginEventType<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PluginLoadOver, //所有插件加载完毕<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PluginAdded,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//插件新增完毕<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PluginRemoved,&nbsp;&nbsp;//插件卸载完毕<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PluginStopped,&nbsp;&nbsp; //插件管理器已停止<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PluginStarted&nbsp;&nbsp;&nbsp;&nbsp; //插件管理器已启动<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp; </div></div><br/><br/>&nbsp;&nbsp; 插件的事件参数定义如下，只包含简单的事件类型和文本描述：<br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;<div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.xiaozhou.net/cooldog/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>&nbsp;&nbsp;&nbsp;&nbsp;public class PluginEventArgs : EventArgs<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#region Private Members<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public PluginEventType EventType { get; set; }<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public string EventMessage { get; set; }<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#endregion<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public PluginEventArgs(PluginEventType eventtype, string message)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EventType = eventtype;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EventMessage = message;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp; </div></div><br/><br/>&nbsp;&nbsp; 以上是使用该插件，需要配置的地方，下一篇日志，将演示该插件的Demo.<br/>]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.xiaozhou.net/cooldog/article.asp?id=188" /> 
	  <id>http://www.xiaozhou.net/cooldog/default.asp?id=188</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[Dynamic Plugins Manager (一) 介绍]]></title>
	  <author>
		 <name>cooldog</name>
		 <uri>http://www.xiaozhou.net/cooldog/</uri>
		 <email>yexiaozhou2003[AT]hotmail.com</email>
	  </author>
	  <category term="" scheme="http://www.xiaozhou.net/cooldog/default.asp?cateID=16" label="我的拙作" /> 
	  <updated>2008-03-29T14:55:32+08:00</updated>
	  <published>2008-03-29T14:55:32+08:00</published>
		  <summary type="html"><![CDATA[&nbsp;&nbsp;Dynamic Plugins Manager是一个基于.NET的动态插件管理组件，也是我在业余时间做的一个小东东，代码在07年底就开始动工，因为一直没充裕时间完成，趁这个周末休息，加班加点的Coding，出来了一个原型，估计里面还有很多的显而易见的以及隐而未现的bug。<br/>&nbsp;&nbsp;设计这个组件的初衷，是为了能方便的应用于今后的项目中。先进的企业级项目中，变化最为突出的，还是业务，业务的变化，直接导致编码中业务逻辑代码的变化。如果将这些业务逻辑混杂在一起，业务的变化，最终会导致代码的混乱，甚至难以维护。这对于一个长期迭代的项目来说，是相当痛苦的事。就像直接拿一个成千上万行的代码给开发人员，估计开发人员不是晕厥，就是吐血。而一个难以维护的业务逻辑代码，对于每一次迭代，都是一次冒险。很可能在某次的迭代中，会对以前的业务逻辑，产生影响或者风险。<br/>&nbsp;&nbsp;对于复杂的业务逻辑，需要进行重构，并且将不断变化的业务逻辑，抽离出来。比较折中的方法，就是将这些变化的逻辑，做成独立的插件形式。这样一来，独立的业务，在物理上进行了分离。开发人员也不用担心修改某处业务逻辑，会影响其他的业务模块。而动态的插件管理形式，对后期维护也带来益处，独立的业务逻辑插件之间，不会相互影响。开发人员还可以在程序运行而又不影响业务的情况下，动态的发布、替换原有的业务逻辑模块。<br/>&nbsp;&nbsp;Dynamic Plugins Manager(以下简称Plugins Manager)，也就是按照这样的思路和需求来设计的，其实现的功能，具体有一下几个特点：<br/>&nbsp;&nbsp;1.所有的插件，都以DLL程序集的方式发布,Plugins Manager在启动的时候，搜索加载所有可加载的插件并进行加载<br/>&nbsp;&nbsp;2.Plugins Manager，支持插件的动态卸载功能。借助于AppDomain的特性，所有的组件，在动态加载后，可以动态从内存中卸载。插件的实现，需要继承自MarshalByRefObject。<br/>&nbsp;&nbsp;3.与接口无依赖性，Plugins Manager负责插件的管理、动态加载、动态卸载、调用。但是和具体的插件接口无关，这样一来，开发人员可以定义自己的插件接口，并开发不同的插件实现接口。<br/>&nbsp;&nbsp;4.插件可以动态发布和卸载,Plugins Manager会监视当前目录中，插件的变化，对于以xcopy方式，拷贝入插件目录的插件，可以进行动态加载。对于插件的卸载，可以Plugins Manager提供的接口进行动态卸载，也可以实时更改插件配置文件中的具体开关进行卸载。<br/>&nbsp;&nbsp;5.动态编译功能：Plugins Manager允许直接发布插件代码。通过读取插件配置文件中的引用信息，可以直接从代码生成dll插件，并加载。<br/>&nbsp;&nbsp;6.允许插件实现不同的构造函数重载，并将构造函数参数以及值信息，定义在插件配置文件中。Plugins Manager在加载插件的时候，采用配置文件中的值，调用相应的构造函数，并加载插件。<br/>&nbsp;&nbsp;7.事件通知：Plugins Manager在不同的插件操作完成后，会触发相应的事件机制，通知客户端程序进行相应的处理<br/><br/>&nbsp;&nbsp;插件的结构一览：<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/><img src="http://www.xiaozhou.net/cooldog/pics/PluginManager/PluginManager.jpg" border="0" alt=""/><br/><br/>&nbsp;&nbsp; PluginsManager:插件管理类，实现插件功能的主要代码逻辑，以及对插件容器的维护<br/>&nbsp;&nbsp; AssemblyLoader:插件加载类，实现从AppDomain加载插件的逻辑<br/>&nbsp;&nbsp; PluginEntity:插件实体类，包含插件的信息(插件实例、插件名称……)<br/>&nbsp;&nbsp; AssemblyFactory:插件生成类，实现从插件代码生成dll的功能<br/><br/>&nbsp;&nbsp;下一篇日志中，将会介绍这个插件的具体配置，及简单分析其实现。]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.xiaozhou.net/cooldog/article.asp?id=187" /> 
	  <id>http://www.xiaozhou.net/cooldog/default.asp?id=187</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[Dynamic Plugins Manager]]></title>
	  <author>
		 <name>cooldog</name>
		 <uri>http://www.xiaozhou.net/cooldog/</uri>
		 <email>yexiaozhou2003[AT]hotmail.com</email>
	  </author>
	  <category term="" scheme="http://www.xiaozhou.net/cooldog/default.asp?cateID=16" label="我的拙作" /> 
	  <updated>2008-03-29T14:47:15+08:00</updated>
	  <published>2008-03-29T14:47:15+08:00</published>
		  <summary type="html"><![CDATA[Dynamic Plugins Manager (一) 介绍<br/><a href="http://www.xiaozhou.net/cooldog/article.asp?id=187" target="_blank" rel="external">http://www.xiaozhou.net/cooldog/article.asp?id=187</a><br/><br/>Dynamic Plugins Manager (二) 配置及实现分析<br/><a href="http://www.xiaozhou.net/cooldog/article.asp?id=188" target="_blank" rel="external">http://www.xiaozhou.net/cooldog/article.asp?id=188</a><br/><br/>Dynamic Plugins Manager (三) Demo <br/><a href="http://www.xiaozhou.net/cooldog/article.asp?id=189" target="_blank" rel="external">http://www.xiaozhou.net/cooldog/article.asp?id=189</a><br/><br/>Dynamic Plugins Manager (四) 插件及Demo源码下载<br/><a href="http://www.xiaozhou.net/cooldog/article.asp?id=190" target="_blank" rel="external">http://www.xiaozhou.net/cooldog/article.asp?id=190</a><br/><br/>Dynamic Plugins Manager (五) Plugins Manager 源码下载<br/><a href="http://www.xiaozhou.net/cooldog/article.asp?id=191" target="_blank" rel="external">http://www.xiaozhou.net/cooldog/article.asp?id=191</a>]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.xiaozhou.net/cooldog/article.asp?id=186" /> 
	  <id>http://www.xiaozhou.net/cooldog/default.asp?id=186</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[迟来的照片--洛带游记]]></title>
	  <author>
		 <name>cooldog</name>
		 <uri>http://www.xiaozhou.net/cooldog/</uri>
		 <email>yexiaozhou2003[AT]hotmail.com</email>
	  </author>
	  <category term="" scheme="http://www.xiaozhou.net/cooldog/default.asp?cateID=17" label="随笔" /> 
	  <updated>2008-01-05T13:40:39+08:00</updated>
	  <published>2008-01-05T13:40:39+08:00</published>
		  <summary type="html"><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;来公司后，和同事们的第一次出行，目的地定在古镇洛带。同学们积极性都很高，在一个周六的早上，相约出发，在目的地会合。游古城，啃玉米，爬长城，晚上又一起唱歌，很是尽兴。因为有同事即将离开成都去重庆开展项目。<br/><br/>发几张照片留念<br/><br/>集体照<br/><img src="http://www.xiaozhou.net/cooldog/photo/content/journey/luodai/100b3724.jpg" border="0" alt=""/><br/><br/>长城上<br/><img src="http://www.xiaozhou.net/cooldog/photo/content/journey/luodai/100_4031.jpg" border="0" alt=""/><br/><br/>著名的伤心凉粉<br/><img src="http://www.xiaozhou.net/cooldog/photo/content/journey/luodai/100_3855.jpg" border="0" alt=""/><br/><br/>摆造型<br/><img src="http://www.xiaozhou.net/cooldog/photo/content/journey/luodai/100_3999.jpg" border="0" alt=""/><br/><br/>更多的照片，看相册哦  <img src="http://www.xiaozhou.net/cooldog/images/smilies/icon_cool.gif" border="0" style="margin:0px 0px -2px 0px" alt=""/><br/><br/><br/>]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.xiaozhou.net/cooldog/article.asp?id=185" /> 
	  <id>http://www.xiaozhou.net/cooldog/default.asp?id=185</id>
  </entry>	
		
</feed>
