没有合适的资源?快使用搜索试试~ 我知道了~
SharpDevelop代码分析
需积分: 11 11 下载量 109 浏览量
2012-03-13
12:59:32
上传
评论
收藏 773KB DOC 举报
温馨提示
试读
36页
SharpDevelop代码分析 感觉挺不错的一个文档,适合有经验C#高手学习。
资源推荐
资源详情
资源评论
下载 SharpDevelop 2.2.1 的源代 码 , 安装 SharpDevelop 安装包, 然 后 用 SharpDevelop 打开
SharpDevelop 的源码,点“Build Solution”,报错,提示没有 FxCop。
到网上找到 FxCop 1.35 和 1.36 Beta 2,安装了前面的版本,注意安装路径不要有空格,否则 Build
仍然会失败。
设置 SharpDevelop 的选项(Tools->Options->Tools->Code Analysis),设置一下 FxCop 的安装
路径。
重新点“Build Solution”,成功!
也可以使用 MSBuild 编译,不过好像需要添加 FxCop 的环境变量,否则编译到最后也会有类似于
“找不到 FxCop”的错误,或者打开 Visual Studio 2005 的命令行后再运行 MSBuild,编译成功。
SharpDevelop 代码分析 (一、序+基本概念)
序
最近开始学习.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(句柄)有一拼了。词典中还有一个翻译
叫“基码”,我觉得这个也不算好,不过还稍微有那么一点意思。
根据我对代码的理解,Codon 描述(包装)一个功能模块,一个功能模块对应一个实现
了具体功能的 Command 类。为了方便访问各个插件中的功能模块, Codon 给各种功
能定义了基本的属性,分别是 ID (功能模块的标识),Name (功能模块的类型。别误会,
这个 Name 是 addin 文件定义中 Codon 的 XML 结点的名称,ID 才是真正的名称),其中
Name 可能是 Class(类)、MenuItem(菜单项)、Pad(面板)等等。根据具体的功能模块,
可 以 继 承 Codon 定 义 其 他 的 一 些 属 性 , SharpDevelop 中 就 定 义 了
ClassCodon、MenuCodon、PadCodon 等等。
在 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。例如 MenuCodon 对应 MenuCommand 等等。
6、Service 服务
插件系统中,有一些功能是整个系统都要使用的,例如文件访问、资源、消息等等。这
些功能都作为插件系统的一个基本功能为整个系统提供服务,我们就叫“服务”好了。为了
便于访问,这些服务都统一通过 ServiceManager 来管理。其实服务也是一种类型的插
件,它们的扩展点路径在目录树中的 /Services 中。
理解了这几个基本的概念之后,就可以看看 SharpDevelop 的代码了。从 src\main\
startup.cs 看起吧,之后是 addin.cs、addinTree.cs等等。
写了两个小时了,休息一下。且听下回分解吧。
SharpDevelop 源码分析 (二、头绪)
在大学课程里面,我对于模拟电路总是搞不清楚,直到现在也是这样。我总觉得电路图很
奇怪,总会问“这部分电路是做什么用的”、“为什么会有这样的效果”。在我的脑海里面,每
部分的电路都应该有一定的用处,可是我总是看不明白。我妈妈说,我的思路被软件所固
化的太久了,看电路图不应该总是一个个模块的看,正确的方法应该是从电源的一极顺着
电路看,一直看到电源的另一极。我现在仍然不懂看电路图,可是以我看代码的经验来说,
我觉得分析源代码按照这样的思路来看会比较容易把脉络理清楚。
在 SharpDevelop 的代码中,由于很多的接口和插件的原因,很多代码在看到某个地
方会突然失去函数/方法调用的线索。例如看某个函数的实现的时候会跳到一个接口里面去,
那是因为这部分功能在运行期才会给一个实现了这个接口的对象来进行具体的执行。从这
个角度来说,设计模式也给我们研究代码稍微带来了一点小小的难度。在看 Linux 下源代
码的时候也经常遇到这种问题,在这个时候寻找代码线索比较好的方法是用一个文本搜索
工具来搜索相关的关键字。在 Linux 下我经常会用 grep,Windows 下面类似 UltraEdit
的“批量文件查找”功能会很好用(或者“Search And Replace”之类的工具)。这个是我
读代码的一点小小的经验,如果你知道有更好的方法,请告诉我让我也学习一下 ? 。
我不想大段大段的贴代码出来占地方(空间、带宽,还有各位看官的注意力),在需
要的地方我会贴上主要的代码,因此最好能够找代码来对应着看。把代码包解压缩,我把
它解到了“F:\SharpDevelop”(如果没有说明,下文都是以此为代码的根目录了)。由于
SharpDevelop 本身对于察看代码不是很方便,没有“转到定义”之类的功能,因此我建议
你把它的代码转成 VS 的工程来看。不过很可惜,SharpDevelop 的工程导出功能现在有
问题,如果导出\src\SharpDevelop.cmbx 这个总的复合工程的话会失败(我记得 RC1
版本是可以成功的,不知道为什么后来的版本反而会出问题),所以只能一个一个工程的
导出。
好了,让我们来看 SharpDevelop 的代码吧。
1、小技巧的起点
在主程序的起点在\src\Main\StartUp\SharpDevelopMain.cs,找到 Main 函数这就
是整个程序的起点了。开始的部分是显示封面窗体并加上命令行控制,其中
SplashScreenForm 定义在\src\Main\Base\Gui\Dialogs\SplashScreen.cs 文件中,
这部分我就不多说了。之后是
Application.ThreadException += new
ThreadExceptionEventHandler(ShowErrorBox);
SharpDevelop 为了有效的进行错误报告,因此自己进行了异常的控制。系统出现异常
的时候,SharpDevelop 会拦截下来弹出它自己的异常提示报告对话框。这个代码就是在
这一行实现的。其中 ShowErrorBox 这个方法就在类 SharpDevelopMain 中,
ExceptionBox 定义在\src\Main\StartUp\Dialogs\ExceptionBox.cs 中。如果需要进
行自己的异常控制,可以学习一下这里的技巧。
2、充满玄机的初始化
string [] addInDirs =
剩余35页未读,继续阅读
资源评论
海盗阿里
- 粉丝: 8
- 资源: 7
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 高等数学第一章第二节数列的极限
- Python 版冒泡排序算法源代码
- tensorflow-gpu-2.7.2-cp38-cp38-manylinux2010-x86-64.whl
- tensorflow-2.7.3-cp39-cp39-manylinux2010-x86-64.whl
- tensorflow-2.7.2-cp39-cp39-manylinux2010-x86-64.whl
- Python版本快速排序源代码
- Python 语言版的快速排序算法实现
- 450815388207377安卓_base.apk
- 超微主板 X9DRE-TF+ bios 支持 nvme启动
- 基于Python通过下载气象数据和插值拟合离散数据曲线实现对寒潮过程的能量分析
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功