SharpDevelop中Addin插件系统的详解(一)

来源:互联网 发布:ubuntu 14.10 更新源 编辑:程序博客网 时间:2024/04/29 11:06

SharpDevelopAddin插件系统的详解(一) 

相信会有很多的Programmer们对换“插件”这一术语都会抱有很大的兴趣,而#SharpDevelopr中的插件系统正以它较大的灵活性、可扩展性吸引了从多Programmer的目光。

(关于#SharpDevelop源码,可以去http://sourceforge.com下载。)  

 

1.   服务概念与Addin插件系统的结合

     在剖析Addin插件系统之前,我们还是要首先来了解一下#SharpDevelop中的Service(服务)概念,这也正是基于#SharpDevelopAddin插件系统与Service服务紧密结合所作出一种考虑。

     在剖析Addin插件系统之前,我们还是要首先来了解一下#SharpDevelop中的Service(服务)概念,这也正是基于#SharpDevelopAddin插件系统与Service服务紧密结合所作出一种考虑。

    #SharpDevelop中的服务,是指用于提供一些诸如“OpenFile”功能的类。在#SharpDevelop中,为了保证这些服务类的可替换性、可扩展性以及服务类的简单定位功能,引入了用于管理这些服务类的ServiceManager类。由于该ServiceManager类采用了Singleton设计模式,从而保证了在#SharpDevelop的任一部分均可方便地获取、使用这些服务类。

    以下为与服务概念相关的一些源码,读者可从SharpDevelop/src/Main/Core/ServicesSharpDevelop/src/Main/Base/Services中获取。        

//////////////////////////////////////////////////////////////////////////////////////////////////////////////// 

public class ServiceManager

{

     ArrayList serviceList       = new ArrayList();

     Hashtable servicesHashtable = new Hashtable();

     // Singleton design pattern.

     static ServiceManager defaultServiceManager = new ServiceManager();

     /// <summary>

     /// Gets the default ServiceManager

     /// </summary>

     public static ServiceManager Services 

     {

         Get { return defaultServiceManager; }

     }

     /// <summary>

     /// Don't create ServiceManager objects, only have ONE per application.

     /// </summary>

     private ServiceManager()

     {

         // add 'core' services

         AddService(new PropertyService());

         AddService(new StringParserService());

         AddService(new FileUtilityService());

     }

 

     /// <remarks>

     /// This method initializes the service system to a path inside the add-in tree.

     /// This method must be called ONCE.

     /// </remarks>

     public void InitializeServicesSubsystem(string servicesPath)

     {

         // add add-in tree services

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

        // initialize all services

         foreach (IService service in serviceList)

         {

              DateTime now = DateTime.Now;

              service.InitializeService();

         }

     }

 

     /// <remarks>

     /// Calls UnloadService on all services. This method must be called ONCE.

     /// </remarks>

     public void UnloadAllServices()

     {

         foreach (IService service in serviceList) 

         {

              service.UnloadService();

         }

     }

     public void AddService(IService service)

     {

         serviceList.Add(service);

     }

 

     public void AddServices(IService[] services)

     {

         foreach (IService service in services) 

         {

              AddService(service);

         }

     }

     // HACK: MONO BUGFIX

     // this doesn't work on mono:serviceType.IsInstanceOfType(service)

     bool IsInstanceOfType(Type type, IService service)

     {

         Type serviceType = service.GetType();

         foreach (Type iface in serviceType.GetInterfaces()) 

         {

              if (iface == type) 

              {

                   return true;

              }

         }

         while (serviceType != typeof(System.Object)) 

         {

              if (type == serviceType) 

              {

                   return true;

              }

              serviceType = serviceType.BaseType;

         }

         return false;

     }

     /// <remarks>

     /// Requestes a specific service, may return null if this service is not found.

     /// </remarks>

     public IService GetService(Type serviceType)

     {

         IService s = (IService)servicesHashtable[serviceType];

         if (s != null

         {

              return s;

         }

         

         foreach (IService service in serviceList) 

         {

              if (IsInstanceOfType(serviceType, service)) 

              {

                   servicesHashtable[serviceType] = service;

                   return service;

              }

         }

         

         return null;

     }

} 

///////////////////////////////////////////////////////////////////////////////////////////////////////////////

/// <summary>

/// This interface must be implemented by all services.

/// </summary>

public interface IService

{

     /// <summary>

     /// This method is called after the services are loaded.

     /// </summary>

     void InitializeService();

         

     /// <summary>

     /// This method is called before the service is unloaded.

     /// </summary>

     void UnloadService();

         

     event EventHandler Initialize;

     event EventHandler Unload;

}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////

       

        值得我们关注的代码行有:

       

        值得我们关注的代码行有:

     // add add-in tree services

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

       该语句将从Addin插件树中获取所要加载的所有服务类,并将这些服务类初始化后加入到服务管理容器中。由于Addin插件树是根据一系列的*.Addin文件创建的,所以它具有很强的可替换性、可扩展性。

同时,通过ServiceManager类的Service GetService(Type serviceType)方法,可以很轻易地获取服务管理容器中的任意类型的服务类。

例如,要获取服务管理容器中的IMessageService类,可经以下语句获取:

IMessageService servicer = (IMessageService)ServiceManager.Services.GetService(typeof(IMessageService));

 

 (未完待续)

 

 (未完待续)

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 dnf刷图卡住了怎么办 dbf深渊怪卡住了怎么办 dnf86级没任务了怎么办 dnf二觉任务没了怎么办 脚趾甲变空向上翘怎么办 汽油车加了一点柴油怎么办 柴油车辆环保检测功率不足怎么办 加95加错一次92怎么办 新车95加错92油怎么办 加不到95号汽油怎么办 去新疆没95号油怎么办 黄龙300加了92怎么办 gla错加92号油 怎么办 95和98混加了怎么办 沥青车可以停在居民区怎么办 汽油进到眼睛了怎么办 汽油进了眼睛里怎么办 眼睛里面进了汽油怎么办 脱硫塔里的二氧化硫高怎么办 恐怖黎明铁匠选错怎么办 堡垒之夜草变色怎么办 火柴没有擦的了怎么办 乙醚倒进下水道了怎么办 乙醚和水不分层怎么办 乙醚闻多了头晕怎么办 爱乐维吃了便秘怎么办 刮完滑石粉墙面很软怎么办 被硫酸泼到皮肤怎么办 头磕了一下头晕怎么办 家里有事与工作不能请怎么办 撞了头头晕想吐怎么办 猫不小心摔一下怎么办 一氧化二氮中毒怎么办 电脑开机变慢了怎么办 怎么办抚顺韦德健身卡 预售健身卡合法吗怎么办 被浓硫酸泼到怎么办 婴儿误喝了生水怎么办 宝宝喝了生水拉肚子怎么办 因妈妈喝生水宝宝拉肚子怎么办 喝了几口生水怎么办