SharpDevelop解析与学习心得之二------重要概念及核心程序的启动
基本概念
要理解SD,首先要弄清楚几个概念是至关重要的。
1、addIn插件树
SharpDevelop 中的插件被组织成一棵插件树结构,树的结构是通过 Path中定义name来定义的,类似一个文件系统的目录结构。系统中的每一个插件都在配置文件中指定了 Path,通过name中指定的路径挂到这棵插件树上。在系统中是用一个静态类来AddInTree来表示的,以此来实现插件间的互动。插件树描述了整个插件系统的逻辑结构
2、 AddIn 插件
在 SharpDevelop 的概念中,插件是包含多个功能模块的集合。在文件的表现形式上是每一个插件配置文件(*.addin文件)都是一个插件,在系统中对应 AddIn 类。
3、Path扩展点
SharpDevelop中的每一个插件都会被挂到 AddInTree(插件树) 中,而具体挂接到这个插件树的哪个位置,则是由插件的Path来指定的。在addin 配置文件中,对应于 <Path> 。例如下面这个功能模块的配置
<Pad id = "ProjectBrowser"
category = "Main"
title = "${res:MainWindow.Windows.ProjectScoutLabel}"
icon = "PadIcons.ProjectBrowser"
shortcut = "Control|Alt|L"
class = "ICSharpCode.SharpDevelop.Project.ProjectBrowserPad"/>
</Path>
Path节点中的name属性指定了它下面节点所在(addinTree)插件树中的位置/SharpDevelop/Workbench/Pads"
4、Codon代码子
Condon 是SD的开发人员规定的名字,中文的意思在网上支持最多的是“代码子”在插件的配置文件中,它表示插件的一个功能模块,即上面提到的Path下面的节点,如:
category = "Main"
title = "${res:MainWindow.Windows.ProjectScoutLabel}"
icon = "PadIcons.ProjectBrowser"
shortcut = "Control|Alt|L"
class = "ICSharpCode.SharpDevelop.Project.ProjectBrowserPad"/>
<ToolbarItem id = "FontFamily"
type = "ComboBox"
tooltip = "${res:Geochem.Grid.ToolBar.FontFamily}"
class = "Jurassic.Geochem.Grid.Commands.FontFamily"/>
condon描述的是具体的功能模块(一个功能模块对应一个实现了具体功能的 Command 类),condon有着不同的类型,代表着不同的意义,比如有上面提到的Pad Condon,ToolbarItem Condon,还有MenuItem Condon,相同的是每个condon都有一个id,表示的是此代码子(功能模块)在SD中的唯一标识。其中还有多很描述这个codon的属性,在上面的pad中,一个pad节点定义的是在SD界面中可以看到的面板,title属性指它的标题的文字,这里用的是系统嵌入的资源文件中名为“mainWindow.Windows.ProjectScoutLabel”所代表的字符,icon属性指的是面板上的图标显示,这里也是嵌入的资源文件中的名为PadIcons.ProjectBrowser所代表的图标,shortCut是此面板对应的快捷键的定义,class则是实现面板功能的类。在程序运行期间利用反射将Class中的类创建出来,反射技术是以往的其它语言所没有的。
5、Doozer解析器
是比Condon节点更具体的实例,用以创建具体的Object对象,即把上面所说的condon变成具体的System.Windows.Forms.ToolBar 系统中有许多不同类型的Doozer,用以生成不同的具体的对象,如MenuItemDoozer, ToolBarItemDoozer, FileFilterDoozer, IncludeDoozer下面是一个ToolbarItemDoozer类,为了不占篇幅,去掉了一些其它的属性,只留下个核心的方法。
{
public object BuildItem(object caller, Codon codon, ArrayList subItems)
{
string type = codon.Properties.Contains("type") ? codon.Properties["type"] : "Item";
bool createCommand = codon.Properties["loadclasslazy"] == "false";
switch (type) {
case "Separator":
return new ToolBarSeparator(codon, caller);
case "CheckBox":
return new ToolBarCheckBox(codon, caller);
case "Item":
return new ToolBarCommand(codon, caller, createCommand);
case "ComboBox":
return new ToolBarComboBox(codon, caller);
case "DropDownButton":
return new ToolBarDropDownButton(codon, caller);
case "ColorPicker":
return new ToolStripColorPicker(codon,caller);
default:
throw new System.NotSupportedException("unsupported menu item type : " + type);
}
}
此方法根据ToolBarItme具体不同的类型,创建不同的ToolBarItem。主doozer全部直接由SharpDevelopMain.cs添加。
6、Command 命令
正如前文所述,Codon描述了一个功能模块,而每个功能模块都是一个 ICommand 的实现。最基本的 Command 是 AbstractCommand,根据Codon的不同对应了不同的 Command。例如 MenuItemCodon 对应 MenuItemCommand 等等。
7、Service 服务
在SharpDevelop中,使用一些静态方法来协助主流程来完成一些额外的扩展的细小的功能,这些功能是整个系统都要使用的,例如文件访问、资源、属性、消息等等。这些功能都作为插件系统的一个基本功能为整个系统提供服务,我们就叫“服务”。为了便于访问,这些服务都是静态的,用类名就可以直接访问,例如MessageService,FileService语言服务LanguageService等等。
MenuService创建menu及MenuItem
LogingService日志服务,辅助系统创建日志
MessageService消息服务,消息输出及处理
ToolbarService工具条服务,工具项的创建
ResourceService资源服务,系统统资源管理,加载
PropertyService属性服务
弄清了上面的基本概念,准备工作就绪,从现在开始研究sharpdevelop的代码吧,首先从起始位置harpDevelopMain.cs主程序的启动开始吧!
研究初步---主程序执行过程
SD从startUp项目的SharpDevelopMain.cs开始启动。在程序开始运行的时候首先
1. 启动一个欢迎屏幕,它定义在StartUp项目Dialogs下面。
2. 然后以反射的方式启动主程序
3. 创建核心对象CoreStartUp
4. 以此对象加载系统核心服务,加载资源文件,查找所有的插件配置文件,
5. 载入插件树(addintree.Load方法。这个比较关键,是插件形成的核心部分);
6. 运行所有"/Workspace/Autostart"目录下的Command。
7. WorkbenchSingleton.InitializeWorkbench();初始化用户界面(这个以后要详细的说一说)。
完成的工作大致有:
1)加载布局文件,布局信息是每次窗口Closing事件中保存的,如果没有保存过,这是默认设置;
2)创建Workbench窗口;
3)初始化Workbench的工作区,现在插件开始派上用场,这里首先开始创建"/SharpDevelop/Workbench/Pads"目录下的