刘金雨

凡所有相,皆是虚妄,若见诸相非相,即见如来

刘金雨ID:passos
40157次访问,排名2611好友5人,关注者11
老程序员。。。
passos的文章
原创 12 篇
翻译 1 篇
转载 8 篇
评论 84 篇
古月春秋的公告

敝人姓刘,名云涛,字金雨。

古月春秋的专栏
最近评论
passos:编译倒是过了,不过这好几年了,找找看。。。
829939:不知道您重新编译过了没

发出来分享一下啊

这个bug让mysql5用起来很烦人的
ddd:不知道楼上的哥哥,哪位知道从那里下载SharpDevelop的源码呢?我从上面的地址连接过去,告诉我"找不到服务器"
passos:Believe or not, as a developer in this team, I do not know this international release before it does...maybe it is sound funny, but that is fact.

In my personal opinion, the release actio……
古月春秋:TO:AJU
如果要在工具栏中插入一个新的功能。也就是新做一个插件,一般的来说要这么几个步骤:
1、确定你的插件是哪种类型的,找到对应的Codon接口/抽象类继承
2、实现Codon中的抽象方法,也就是你的插件功能
3、找到对应的扩展点,在配置文件中把你的插件挂到这个扩展点下面去

例如你要在工具栏中加入一个按钮,那么可以先从配置文件中查找一下……
文章分类
收藏
相册
存档
订阅我的博客
XML聚合  FeedSky

原创 SharpDevelop源码分析 (一、序+基本概念)收藏

新一篇: SharpDevelop源码分析 (二、主程序+隐藏的初始化) | 旧一篇: // I have a comment ----Delphi 研发人员谈注释 (翻译版)



    最近开始学习.Net,遇到了一个比较不错的开源的IDE SharpDevelop。这个开发工具是使用C#开发的,比较吸引我的一点就是它是采用了和Eclipse类似的插件技术来实现整个系统的。而这个插件系统是我最感兴趣的地方,因此开始了一段代码的研究。在本篇之后,我会陆续把我研究的心得写下来。由于是在网吧上网,有诸多不便,因此可能会拖比较长的时间。



一、基本概念

    首先,我们先来对 SharpDevelop 有一个比较感性的认识。你可以从这里下载到它的可执行程序和代码包    http://www.icsharpcode.com/  ,安装的废话就不说了,先运行一下看看。感觉跟VS很像吧?不过目前的版本是1.0.0.1550,还有很多地方需要完善。关于代码和系统结构,SharpDevelop的三个作者写了一本书,各位看官可以参考一下,不过我看过之后还是有很多地方不太理解。

    然后,让我来解释一下什么叫插件以及为什么要使用插件系统。我们以往的系统,开发人员编译发布之后,系统就不允许进行更改和扩充了,如果要进行某个功能的扩充,则必须要修改代码重新编译发布。这就给我们带来了比较大的不方便。解决的方法有很多,例如提供配置等等方法。在解决方案之中,插件是一个比较好的解决方法。大家一定知道PhotoShop、WinAmp吧,他们都有“插件”的概念,允许其他开发人员根据系统预定的接口编写扩展功能(例如PhotoShop中各种各样的滤镜)。所谓的插件就是系统的扩展功能模块,这个模块是以一个独立文件的形式出现的,与系统是相对独立。在系统设计期间并不知道插件的具体功能,仅仅是在系统中为插件留下预定的接口,系统启动的时候根据插件的配置寻找插件,根据预定的接口把插件挂接到系统中。

    这样的方式带来什么样的优点呢?首先是系统的扩展性大大的增强了,如果我们在系统发布后需要对系统进行扩充,不必重新编译,只需要修改插件就可以了。其次有利与团队开发,各个功能模块由于是以插件的形式表现在系统中,系统的每日构造就很简单了,不会因为某个模块的错误而导致整个系统的BUILD失败。失败的仅仅是一个插件而已。

    PhotoShop和Winamp的插件系统是比较简单的,他们首先实现了一个基本的系统,然后在这个系统的基础上挂接其他扩展的功能插件。而SharpDevelop的插件系统更加强大,它的整个系统的基础就仅仅是一个插件管理系统,而你看到的所有的界面、功能统统都是以插件的形式挂入的。在这样的一个插件系统下,我们可以不修改基本系统,仅仅使用插件就构造出各种各样不同的系统。

    现在让我们来看看它的插件系统。进入到SharpDevelop的安装目录中,在Bin目录下的SharpDevelop.exe 和 SharpDevelop.Core.dll是这个系统的基本的插件系统。在Addins目录下有两个后缀是addin的文件,其中一个 SharpDevelopCore.addin 就是它的核心插件的定义(配置)文件,里面定义的各个功能模块存在于Bin\Sharpdevelop.Base.dll 文件中,另外还有很多其他的插件定义在Addins目录下的addin文件中。

    分析SharpDevelop的代码,首先要弄清楚几个基本的概念,这些概念和我以前的预想有一些区别,我深入了代码之后才发现我的困惑所在。

1、AddInTree  插件树
    SharpDevelop 中的插件被组织成一棵插件树结构,树的结构是通过 Extension(扩展点)中定义的Path(路径)来定义的,类似一个文件系统的目录结构。系统中的每一个插件都在配置文件中指定了 Extension,通过Extension中指定的 Path 挂到这棵插件树上。在系统中可以通过 AddTreeSingleton对象来访问各个插件,以实现插件之间的互动。

2、 AddIn 插件
    在 SharpDevelop 的概念中,插件是包含多个功能模块的集合(而不是我过去认为的一个功能模块)。在文件的表现形式上是一个addin配置文件,在系统中对应 AddIn 类。

3、Extension 扩展点
    SharpDevelop中的每一个插件都会被挂到 AddInTree(插件树) 中,而具体挂接到这个插件树的哪个位置,则是由插件的 Extension 对象中的 Path 指定的。在addin 配置文件中,对应于 <Extension> 。例如下面这个功能模块的配置

<Extension path = "/SharpDevelop/Workbench/Ambiences">
         
<Class id    = ".NET" class = "ICSharpCode.SharpDevelop.Services.NetAmbience"/>
 
</Extension>

指定了扩展点路径为 /SharpDevelop/Workbench/Ambiences ,也就是在插件树中的位置。

4、Codon
    这个是一个比较不好理解的东西,在 SharpDevelop 的三个作者写的书的中译版中被翻译为密码子,真是个糟糕的翻译,可以跟Handle(句柄)有一拼了。词典中还有一个翻译叫“基码”,我觉得这个也不算好,不过还稍微有那么一点意思。(这里我原来误写为“代码子”,在评论中有位仁兄说这个翻译不错,现在我觉得也好像确实不错 ^o^)
    根据我对代码的理解,Codon 的功能是描述(包装)一个功能模块(一个功能模块对应一个实现了具体功能的 Command 类)。为了方便访问各个插件中的功能模块, Codon 给各种功能定义了基本的属性,分别是 ID (功能模块的标识),Name (功能模块的类型。别误会,这个Name 是addin文件定义中Codon的XML结点的名称,ID才是真正的名称),其中Name可能是Class(类)、MenuItem(菜单项)、Pad(面板)等等。根据具体的功能模块,可以继承Codon定义其他的一些属性,SharpDevelop中就定义了 ClassCodon、MenuItemCodon、PadCodon等等,你可以根据需要自己定义其他类型的Codon。在addin定义文件中,Codon对应于 <Extension> 标签下的内容。例如下面这个定义

<Extension path = "/SharpDevelop/Workbench/Ambiences">
         
<Class id    = ".NET" class = "ICSharpCode.SharpDevelop.Services.NetAmbience"/>
 
</Extension>

<Extension ...> 内部定义了一个Codon,<Class ...>  表示该Codon是一个 Class(类),接着定义了该Codon的 ID和具体实现该Codon的类名ICSharpCode.SharpDevelop.Services.NetAmbience。运行期间将通过反射来找到对应的类并创建出来,这一点也是我们无法在以前的语言中实现的。

再例如这一个定义

 <Extension path = "/SharpDevelop/Views/ProjectBrowser/ContextMenu/CombineBrowserNode">
                
<MenuItem id = "Compile"
                          label 
= "${res:XML.MainMenu.RunMenu.Compile}" 
                          class 
= "ICSharpCode.SharpDevelop.Commands.Compile"/>
                
<MenuItem id = "CompileAll"
                          label 
= "${res:XML.MainMenu.RunMenu.CompileAll}" 
                          class 
= "ICSharpCode.SharpDevelop.Commands.CompileAll"/>
                
<MenuItem id = "CombineBuildGroupSeparator" label = "-" />
 .
</Extension>

这个扩展点中定义了三个菜单项,以及各个菜单项的名字、标签和实现的类名。这里的Codon就对应于系统中的MenuCodon对象。

5、Command 命令
    正如前文所述,Codon描述了一个功能模块,而每个功能模块都是一个 ICommand 的实现。最基本的 Command 是  AbstractCommand,根据Codon的不同对应了不同的 Command。例如 MenuItemCodon 对应 MenuItemCommand 等等。

6、Service 服务
    插件系统中,有一些功能是整个系统都要使用的,例如文件访问、资源、消息等等。这些功能都作为插件系统的一个基本功能为整个系统提供服务,我们就叫“服务”好了。为了便于访问,这些服务都统一通过 ServiceManager 来管理。其实服务也是一种类型的插件,它们的扩展点路径在目录树中的 /Workspace/Services 中。

    理解了这几个基本的概念之后,就可以看看 SharpDevelop 的代码了。从 src\main\startup.cs 看起吧,之后是addin.cs、addinTree.cs 等等。

   写了两个小时了,休息一下。且听下回分解。

发表于 @ 2004年10月04日 18:55:00|评论(loading...)|编辑

评论

#gotoxqc 发表于2005-01-26 18:21:00  IP:
TrackBack来自《SharpDevelop源码分析 (一、序 基本概念) 》

Ping Back来自:blog.csdn.net
#tony 发表于2004-10-06 17:05:00  IP: 210.22.128.*
这本书我是在看到codon时对自己的理解能力彻底失去信心的。。。
#大章鱼 发表于2004-10-06 18:54:00  IP: 220.163.13.*
哈哈哈,楼上的,“彻底失去信心”么,我也是有同感啊
#Kozen 发表于2004-10-08 12:12:00  IP: 218.94.30.*
是件有意义的工作。
希望能够持之以恒!
加油!
#jonescheng 发表于2004-10-08 12:44:00  IP: 218.72.146.*
想看,可惜太懒了。佩服楼主。。
#gccr 发表于2004-10-08 13:36:00  IP: 61.149.156.*
买了这本书。可是一直看不下去。你的这篇文章出现的太是时候了。哈哈。
#byrybye 发表于2004-10-08 09:24:00  IP: 210.22.107.*
希望作者继续,关于插件的地方偶也没有完全理解。支持。
#仪表 发表于2004-10-08 14:18:00  IP: 218.13.192.*
买了这本书
#Turbowang 发表于2004-10-08 14:37:00  IP: 218.58.142.*
文章写的不错,SharpDevelope的代码我读过,那本书我也度过
感觉她的插件实现机制不适那么的自然阿。
还有,在界面工具栏菜单栏与文档窗口的配合更新的实现上,感觉比较的笨重。

不知道各位怎么认为?
#nickelz 发表于2004-10-08 16:40:00  IP: 202.113.177.*
佩服楼上的,我自从买了书,好像还没翻到过第五章呢~~
真是没什么信心了,好像从来没学过语文似的
#cya 发表于2004-10-08 10:51:00  IP: 222.183.86.*
正在阅读
#royeelin 发表于2004-10-08 18:04:00  IP: 219.137.55.*
个人感觉在插件的理念是很好的,只是SD实现的方式不够灵活,如果能通过生成动态属性并生成相应的XML类型文件,就不必严格按当中规定的接口或XML Schema来实现自已的插件,那更好了。另外,SD中通过Code DOM将C#源码转成设计模式(Design Mode)下的可视化设计界面还是值参考的,这样可以实现类似于Visual Studio .Net设计界面。
#飞刀 发表于2004-10-09 13:10:00  IP: 61.144.207.*
SharpDevelop现在的版本还比较难用,不过不代表以后,呵呵。

我没有仔细看过SharpDevelop的插件系统,不过从楼主的表达来说,这套插件系统和Eclipse的插件系统非常相似(可以说是一致),概念也差不多,比如Addin,扩展点这些。

而且,SharpDevelop的作者还写过SWT在.Net下的实现,所以我估计他们应当是模仿的Eclipse的插件系统架构。
#cyclone 发表于2004-10-09 09:05:00  IP: 203.193.29.*
严重同意楼上的。
#Luyan 发表于2004-10-08 20:43:00  IP: 210.53.207.*
呵呵,小刘同志,开始写心得了
#古月春秋 发表于2004-10-09 17:17:00  IP: 220.163.13.*
TO 虫&飞刀:
SD的作者本来就是参考了eclipse的插件系统,连配置文件都很像。不过插件树的结构是eclipse里面没有的,eclipse是通过文件系统的目录结构来表达这个树的概念的吧?不过我对JAVA不是很熟悉,因此不知道是否是这样的
#redbb 发表于2004-10-09 20:02:00  IP: 222.65.55.*
good article
#虫 发表于2004-10-08 23:08:00  IP: 219.224.141.*
其实不如先看看eclipse,然后会发现惊人的相似
#beelzebub918 发表于2004-10-09 10:55:00  IP: 210.22.130.*
书确实有点难懂,谢谢搂主的解释。
从中可以学到不少的东西.
#5drush 发表于2004-10-10 11:22:00  IP: 202.100.200.*
使用插件树结构的好处是可以在企业分布式应用中让服务器来统一管理所有的客户端的插件配置,例如自动化的插件扩展和更新。
这点使用eclipse的插件结构就比较难做到。
#5drush 发表于2004-10-10 21:43:00  IP: 221.11.148.*
to 飞刀:
插件树结构跟跨平台没有什么关系,SharpDevelop一样是跨平台的,如果你看过SD的代码的话,会看到很多的if Linux这样的预编译指令,在LINUX下SharpDevelop叫做MonoDevelop,界面是用GTK#写的,运行在MONO平台下,跟SharpDevelop一样的插件结构。MonoDevelop的网站地址是:http://www.monodevelop.net/
#古月春秋 发表于2004-10-10 22:56:00  IP: 220.163.13.*
插件树的分析在本系列的第三篇文章中,可以参考一下。
#wzy 发表于2004-10-10 23:01:00  IP: 61.50.141.*
我个人认为Codon的思想是很棒的,应该也是设计模式的一个经典实现吧!我曾经将SharpDevelop的这种模式应用到我的系统中,总的来说做基础框架还是不错的,可扩展性是很强大和灵活的,但是随着模块的数量不断增加,同样要为它的那种复杂的分散式的模块配置附出很大的代价,如果大伙将来要使用这种模式,在如何简化配置这个工作上一定要认真思考!
#liangzhimy 发表于2004-10-10 09:40:00  IP: 61.49.121.*
支持, 同感, 正在研究这本书呢
#飞刀 发表于2004-10-10 19:48:00  IP: 219.232.184.*
我不太明白“插件树”的具体概念,暂时也没有时去看那本红皮书,不过从楼主的文中理解,基本上应当是一个配制文件,用于指定每个插件存放的路径。如果是这样的话,我想它确实要比Eclipse的插件体系要灵活,毕竟是模仿别人,肯定要有超出的部分。

(以下所说的前题是,我对"插件树"的理解是正确的)
我想当初IBM的工程师设计Eclipse插件体系时为什么没有插件树,应当是因为跨平台的原因,我不知道SharpDevelop的插件树指定路径时,是否可以使用绝对路径,如果可以,那么这是一个潜在的跨平台问题,因为各平台之间的Path指定是不同的,虽然可以告诉别人不要用绝对路径,但是这事没有绝对,总有人喜欢用,出了问题只会骂你的东东“垃圾”,呵呵,而SharpDevelop目前不需要考虑跨平台的问题。

再者我认为,使用插件树和使用目录管理各有千秋,插件树使用,虽然灵活,但是确意味着,我每加一个插件,需要我手动编辑插件树配制文件,而这时Eclipse只需要把插件丢到plugin目录即可。
#gronlet 发表于2004-10-11 13:10:00  IP: 218.89.190.*
看样子大家都对这个 .Net 'Eclipes' 狠感兴趣哦~
#xiao bo 发表于2005-01-28 10:43:00  IP: 61.144.148.*
运行期间将通过 "反射" 来找到对应的类并创建出来,这一点也是我们无法在以前的语言中实现的。

“通过反射来找到对应的类并创建”
#ddd 发表于2006-02-13 22:20:00  IP: 219.236.60.*
不知道楼上的哥哥,哪位知道从那里下载SharpDevelop的源码呢?我从上面的地址连接过去,告诉我"找不到服务器"
发表评论  


登录
Csdn Blog version 3.1a
Copyright © 古月春秋