分享
 
 
 

SharpDevelop源码分析 (二、头绪)

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

在大学课程里面,我对于模拟电路总是搞不清楚,直到现在也是这样。我总觉得电路图很奇怪,总会问“这部分电路是做什么用的”、“为什么会有这样的效果”。在我的脑海里面,每部分的电路都应该有一定的用处,可是我总是看不明白。我妈妈说,我的思路被软件所固化的太久了,看电路图不应该总是一个个模块的看,正确的方法应该是从电源的一极顺着电路看,一直看到电源的另一极。我现在仍然不懂看电路图,可是以我看代码的经验来说,我觉得分析源代码按照这样的思路来看会比较容易把脉络理清楚。

在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 = ICSharpCode.SharpDevelop.AddInSettingsHandler.GetAddInDirectories( out ignoreDefaultPath );

AddInTreeSingleton.SetAddInDirectories(addInDirs, ignoreDefaultPath);

通过AddInSettingsHandler取得插件的目录,并告知AddInTreeSingleton。AddInSettingsHandler定义在\src\Main\StartUp\Dialogs\AddInTreeSettingsHandler.cs中,它通过读取系统配置(App.config)文件中的AddInDirectory节点的Path属性来确定插件的目录位置,或者你也可以通过自己定义的AddInDirectories节来指定插件目录。如果你没有做这些配置,默认的目录在SharpDevelop运行目录的..\Addins目录下。

ServiceManager.Services.AddService(new MessageService());

ServiceManager.Services.AddService(new ResourceService());

ServiceManager.Services.AddService(new IconService());

通过ServiceManager(服务管理器)加入三个系统默认的服务,消息服务、资源服务、图标服务。这三个服务中,消息服务是显示各种信息提示,另外两个是属于系统的资源,SharpDevelop通过服务来进行统一调用和管理。

ServiceManager.Services.InitializeServicesSubsystem("/Workspace/Services");

初始化其他的服务。SharpDevelop把服务定义在插件树的/Workspace/Services这个路径中,凡是在这个路径下的插件都被认为是服务,因此如果你自己定义了一个服务的话,也需要挂到这个路径下(这里就是系统服务的扩展点了)。

注意!这一步中,在我们的眼皮子底下悄悄的进行了一个重要的初始化工作。各位看官请看,ServiceManager 定义在\src\Main\Core\Services\ ServiceManager.cs文件中,察看它的InitializeServicesSubsystem方法,我们发现这样一行

AddServices((IService[])AddInTreeSingleton.AddInTree.GetTreeNode(servicesPath).BuildChildItems(this).ToArray(typeof(IService)));

在这里,AddInTreeSingleton首次调用了AddInTree(插件树)的实例。按照Singleton模式,只有在首次调用的时候才会初始化实例,这里也是同样如此。整个系统的AddInTree是在这一步中进行了初始化工作,稍候我们将详细介绍AddInTree如何进行初始化工作,先顺便看看服务的初始化。在ServiceManager的InitializeServicesSubsystem方法中,通过AddInTree检索服务插件路径下的所有配置,并通过它来读取、建立具体的对象,然后加入到服务列表中。之后通过一个循环,逐个的调用各个服务的InitializeService方法初始化服务。

AddInTree的初始化工作容我们稍候再看,先把主体的代码看完。

commands = AddInTreeSingleton.AddInTree.GetTreeNode("/Workspace/Autostart").BuildChildItems(null);

for (int i = 0; i < commands.Count - 1; ++i) {

((ICommand)commands[i]).Run();

}

/Workspace/Autostart是系统自动运行命令的扩展点路径,定义在这个路径下的插件会在系统启动的时候自动运行。在这里,通过插件树初始化建立处于这个路径下的Command(命令),并逐一执行。BuildChildItems方法的功能是建立这个扩展点下的Command列表,我会在介绍AddTree的时候具体说明它的实现。

主程序代码的最后,初始化完毕、关闭封面窗体,然后执行命令列表中最后一个命令(也就是系统的主界面)。在主界面退出的时候,系统卸载所有的服务。

在这部分代码中,我们知道了两个系统指定的扩展点路径 /Workspace/Services 和 /Workspace/Autostart ,我们实现服务和指定系统自动运行命令的时候就可以挂到这两个扩展点路径下了。

托反射的福,ServiceManager.Services可以通过类型(接口)来查找具体的实例,也就是GetServices方法。但是ServiceManager的具体实现我们可以容后再看,这里已经不是最紧要的部分了。

接下来,我们来看看整个插件系统的核心-AddinTree的代码,看看它是如何通过插件配置进行初始化并建立起整个系统的插件树骨干。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有