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

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));

 

  (未完待续)

 

  (未完待续)

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值