SharpDevelop源码分析笔记(一)

 

                                                   SharpDevelop源码分析笔记(一)   

                                                                                
                                                              [-Fbt-2005-8-2]
 

引言
:学习.NET已经有一段时间了,而在工作中也常常会碰到一些比较头痛的问题.最常见的就是因为客户要增加某个功能而不得不对程序进行大幅修改.但是由于设计上的缺陷,往往一个地方改动后,会引起其它地方的异常.例如修改全局变量,或窗体间的耦合度太高.这样往往要付出很高的代价才能完成修改工作.所以好的设计会减少以后工作的的很多麻烦.既然有了前车之鉴,这个使用Eclipse类似的插件技术来实现整个系统的开源IDE SharpDevelop自然就吸引了我.好了,言归正传.

 初次使用感觉

启动程序给我的第一感觉就是:比微软的VS2003 要快.界面也很清爽.功能和vs2003差不多,比较实用的就是VB.NET C# 的相互转换功能.好了,赶紧下载源码来看看.  http://www.icsharpcode.com/  为了调试方便先将下载的源码转换为VS2003工程.

 1.       疑惑

可能由于SharpDevelop使用插件树来构建整个系统,在看代码时,感觉很不习惯,往往在看到某个地方时会突然失去函数方法调用的线索,例如看某个函数的实现的时候会跳到一个接口里面去,那是因为这部分功能在运行期才会给出一个实现了这个接口的对象来进行具体的执行。

找到主程序的起点在\src\Main\StartUp\SharpDevelopMain.cs

//系统出现异常的时候,SharpDevelop会拦截下来弹出它自己的异常提示报告对话框。
Application.ThreadException += new ThreadExceptionEventHandler(ShowErrorBox);

很实用的异常捕获方法,可以用到自己的程序中

//ShowErrorBox 方法:
static void ShowErrorBox(object sender, ThreadExceptionEventArgs eargs)
{
     DialogResult result 
= new ExceptionBox(eargs.Exception).ShowDialog();
switch (result) 
{
            
case DialogResult.Ignore:
                  
break;
            
case DialogResult.Abort:
                  Application.Exit();
                  
break;
            
case DialogResult.Yes:
                  
break;
        }

}

//ExceptionBox 定义:
\src\Main\StartUp\Dialogs\ExceptionBox.cs

2. 核心初始化

  

string [] addInDirs = AddInSettingsHandler.GetAddInDirectories(out ignoreDefaultPath); 

AddInTreeSingleton.SetAddInDirectories(addInDirs, ignoreDefaultPath); 
 

//此段代码的意思是查找插件树配置文件的路径,它首先去调用AddInSettingsHandler.GetAddInDirectories()方法,然后查找App.Config中的AddInDirectories这一项,如果在配置文件中不存在这一项的话就返回空值。当调用AddInTreeSingleton.SetAddInDirectories(addInDirs, ignoreDefaultPath)方法时如果addInDirs为空的话那么插件树配置文件的默认路径为 ../Addin/。


try 
{
   
//服务初始化
    ServiceManager.Services.AddService(new MessageService());//消息服务

   
//在找到插件树配置文件路径后首先要启动一个默认的资源服务Resource(该服务为系统的默认服    务,必须启动,否则程序将无法运行)。
ServiceManager.Services.AddService(new ResourceService());//资源服务

    ServiceManager.Services.AddService(
new IconService());  //图标服务

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

//这段代码就是程序启动时加载前台插件了,/Workspace/Autostart是系统自动运行命令的扩展点路径,定义在这个路径下的插件会在系统启动的时候自动运行。在这里,通过插件树初始化建立处于这个路径下的Command(命令),并逐一执行。BuildChildItems方法的功能是建立这个扩展点下的Command列表
 commands = AddInTreeSingleton.AddInTree.GetTreeNode("/Workspace/Autostart").BuildChildItems(null);
 
for (int i = 0; i < commands.Count - 1++i) 
{
        ((ICommand)commands[i]).Run();
    }

}
 
catch (XmlException e) 
{
     MessageBox.Show(
"Could not load XML :" + Environment.NewLine + e.Message);
     
return;
}
 
catch (Exception e) 
{
    MessageBox.Show(
"Loading error, please reinstall :"  + Environment.NewLine + e.ToString());
    
return;
}
 
finally //退出启动界面
{
     
if (SplashScreenForm.SplashScreen != null
{
        SplashScreenForm.SplashScreen.Close();
     }

}

//在消息循环结束时, 卸载所有的服务
try 
{
     
//最后一个命令激活IDE的工作后台窗体(主窗体),并运行消息循环.
if (commands.Count > 0
{
            ((ICommand)commands[commands.Count 
- 1]).Run();
      }

}
 
finally 
{
         ServiceManager.Services.UnloadAllServices();
}

SharpDevelop的启动过程总算搞清楚了,感觉有所启发,而最难于理解的就是, SharpDevelop没有在核心中嵌入任何GUI,而在应用程序实际用到时,才会实现GUI.这样好处是提供了良好的扩展性,但也为读懂程序和调试带来一定的困难.(至少我现在是这样,牛人除外).好了,暂时分析到这,下次接着分析各个细节.写了这久现在背后已经湿了大半,还好公司有空调,明天休息咋办呢?

posted @ 2005-08-02 16:54  永恒的风景  阅读(9271)  评论(9编辑  收藏  举报