zoukankan      html  css  js  c++  java
  • Mussel使用系列(五):插件项目之间的调用

    在上一篇文章中,我们讲过如何从外部调用插件项目,接下来我们来看看插件项目与插件项目之间的调用。

    我们来看看现在的应用场景:同样是对两个数值进行运算,MathOne是基本并且稳定的运算服务,负责对这两个数据相加并返回值。但是由于新的用户的需求发生了改变,他们希望获得的值是MathOne结果的平方数,例如:

    如果我们传入的值是 (2,3),旧用户期望得到的值是 2+3 = 5 ,而新用户期望的值是  MathOne 运算结果的平方数,即是 5  2 = 25。

    由于需要同时考虑新的需求并兼容旧的用户,所以我们需要加多一个插件项来为新用户响应需求。

    为了让大家看起来不那么吃力,我们还是重述一下相关的接口及 MathOne 的实现:

    运算服务的接口定义(程序集:Unit.Contract.dll)
    1. namespace Unit   
    2. {   
    3.     public interface IMath   
    4.     {   
    5.         int Calculate(int value1, int value2);   
    6.     }   
    7. }  
    MathOne - 旧用户用到的运算服务(Unit.MathOne.dll)
    1. using System;   
    2. using Mussel.Addins;   
    3.   
    4. namespace Unit   
    5. {   
    6.     [MusselType("MathOne")]   
    7.     public class MathOne:AddinItem,IMath   
    8.     {   
    9.         public int Calculate(int value1, int value2)   
    10.         {   
    11.             Console.WriteLine("MathOne Calculate:");   
    12.             Console.WriteLine("\t{0} + {1} = {2}",   
    13.                 value1, value2, value1 + value2);   
    14.             return value1 + value2;   
    15.         }   
    16.     }   
    17. }  

    我们再来看看新的运算服务实现:

    MathTwo - 新的运算服务(Unit.MathTwo.dll)
    1. using System;   
    2. using Mussel.Addins;   
    3.   
    4. namespace Unit   
    5. {   
    6.     [MusselType("MathTwo")]   
    7.     public class MathTwo:AddinItem,IMath   
    8.     {   
    9.         private string mathOneKey;   
    10.   
    11.         protected string MathOneKey   
    12.         {   
    13.             get { return ReadProperty(ref mathOneKey, "MathOne"); }   
    14.         }   
    15.   
    16.   
    17.         public int Calculate(int value1, int value2)   
    18.         {   
    19.             Console.WriteLine("MathTwo Calculate:");   
    20.   
    21.             IMath mathOne = FindAddinItem<IMath>(MathOneKey);   
    22.             int result = mathOne.Calculate(value1, value2);   
    23.                
    24.             Console.WriteLine("\t{0} * {0} = {1}",   
    25.                 result,result * result);   
    26.                
    27.             return result * result;   
    28.         }   
    29.     }   
    30. }  

    由于我们需要知道旧的运算服务 - MathOne 插件项目的具体路径,所以,我们引入了一个MathOneKey 的属性,这个属性从插件配置文件(*.addin)中对应的插件项目配置节点来读取相应的特性,用ReadProperty函数读取。ReadProperty函数其实是封装了经典的Double Lock方式,也可以看一下原码:

    C#代码
    1. protected string ReadProperty(ref string field,    
    2.     string propertyName)   
    3. {   
    4.     return ReadProperty(ref field, propertyName, false);   
    5. }   
    6.   
    7. protected string ReadProperty(ref string field,    
    8.     string propertyName, bool forceRead)   
    9. {   
    10.     if (string.IsNullOrEmpty(field))   
    11.         lock (this)   
    12.             if (string.IsNullOrEmpty(field))   
    13.             {   
    14.                 if (forceRead)   
    15.                     field = properties.ConfigPoint.Attributes[propertyName];   
    16.                 else field = Properties.ConfigPoint.GetAttribute(propertyName);   
    17.             }   
    18.     return field;   
    19. }  

    再来看看如何获取到MathOne插件:IMath mathOne = FindAddinItem<IMath>(MathOneKey);

    由于我们已经可以读取MathOne的完全路径,所以就可以很轻松通过上面的方式的取出MathOne。如果指定的插件项目路径有误或是插件项目不存在,上面的FindAddIntem<T>方法就会抛出NoFoundAddinItemException的异常。

    接下来再看看主程序及插件配置文件的代码: 

    主程序的代码(程序集:Unit.Loader.dll)
    1. using System;   
    2. using Mussel;   
    3.   
    4. namespace Unit   
    5. {   
    6.     class Program   
    7.     {   
    8.         static void Main()   
    9.         {   
    10.             MusselService service = new MusselService();   
    11.             service.Start();   
    12.   
    13.             IMath mathOne = 
    14.               service.Container["/Core/Services,MathOne"as IMath;   
    15.   
    16.             if (mathOne != null) mathOne.Calculate(100, 150);   
    17.   
    18.   
    19.             Console.WriteLine();   
    20.   
    21.             IMath mathTwo =   
    22.                 service.Container["/Core/Services,MathTwo"as IMath;   
    23.   
    24.             if (mathTwo != null) mathTwo.Calculate(100, 150);   
    25.   
    26.             Console.ReadLine();   
    27.   
    28.             service.Dispose();   
    29.         }   
    30.     }   
    31. }  
    插件配置文件(Core.addin)
    1. <?xml version="1.0" encoding="utf-8" ?>  
    2. <Addin Name="Core">  
    3.   <ReferenceAssemblies>  
    4.     <Reference AssemblyFile="Unit.MathOne.dll"    
    5.                IsMusselAssembly="true"/>  
    6.     <Reference AssemblyFile="Unit.MathTwo.dll"    
    7.                IsMusselAssembly="true"/>  
    8.   </ReferenceAssemblies>  
    9.   <AddinNode Path="/Core/Services">  
    10.     <AddinItem ClassKey="MathOne"/>  
    11.     <AddinItem ClassKey="MathTwo"    
    12.                MathOne="/Core/Services,MathOne"/>  
    13.   </AddinNode>  
    14. </Addin>  

    可以看到,主程序的代码与上篇中的基本上没有什么差异,有变动的插件配置文件。由于我们在MathTwo中需要从配置文件中读取相应节点的的附加特性(MathOne特性),所以<AddinItem ClassKey="MathTwo" MathOne="/Core/Services,MathOne"/>在这个位置多出了一个插件的自定义特性。

    运行结果:

    点击下载程序源文件

  • 相关阅读:
    Vue源码学习之双向绑定
    Vue源码学习之数据初始化
    JavaScript跨域资源请求(CORS)解决方案
    Vue学习笔记
    MongoDB学习笔记
    实现一个类似bootstrap的多级下拉菜单
    bootstrap栅格系统的实现
    滑动效果的标签页切换
    一个简单的类似Vue的双向绑定
    元素垂直居中的常见方法
  • 原文地址:https://www.cnblogs.com/isuper/p/1239062.html
Copyright © 2011-2022 走看看