考察如下应用:

 

 

 

公司开发某种中间件产品,该产品的主要功能是从上位系统采集数据,并将采集到的数据做某种处理,然后下发到下级系统中。要求该产品要支持不同类型,不同数量,不同数据格式的上位系统,下发时统一发送符合某种规则或格式的数据流。此外,在增加或删除对某一上位模块支持的时候,无需从新编译该中间件产品。本文讨论不同类型,不同数量,不同数据格式的上位系统,在不需重新编译的情况下,动态添加与删除的技术。

一.模块动态加载技术概述

该技术由配置文件和一组设计模式组成,以配置文件为核心,根据配置文件提供的模块信息,通过反射技术实现了增加和删除新模块而无需重新编译系统的功能。

 

二.动态加载模块部分的配置文件格式及注释

<WMS_MODULE>      
    <WMS>
        <ID>1</ID>               <!--模块编号-->
        <PATH>C:\ContreteWMS1.dll</PATH>    <!--具体的WMS引擎模块位置-->
        <ASSEMBLYNAME>ContreteWMS1</ASSEMBLYNAME>        <!--程序集名-->
        <CLASSNAME>ContreteWMS1</CLASSNAME>                <!--类名-->
        <WMS_METHOD>   <!--支持的方法列表-->
             <ID>1</ID>      <!--所属WMS模块编号,同“模块编号”-->
            <METHOD>GetTask</METHOD>    <!--其中一个方法-->
            <INPUT_PARAMETER>NONE</INPUT_PARAMETER>    <!--输入参数类型,NONE为无输入-->
            <RETURN_PARAMETER>System.Data.DataSet</RETURN_PARAMETER>    <!--返回类型-->
        </WMS_METHOD>
        <WMS_METHOD>
             <ID>1</ID>
            <METHOD>SendTask</METHOD> 
            <INPUT_PARAMETER>System.Data.DataSet</INPUT_PARAMETER>
            <RETURN_PARAMETER>NONE</RETURN_PARAMETER>
        </WMS_METHOD>        
    </WMS>
    <WMS>
        <ID>2</ID>
        <PATH>C:\ContreteDemoWMS2.dll</PATH>
        <ASSEMBLYNAME>ContreteDemoWMS2</ASSEMBLYNAME>
        <CLASSNAME>ContreteDemoWMS2</CLASSNAME>             
        <WMS_METHOD>
             <ID>2</ID>
            <METHOD>GetTask</METHOD>    
            <INPUT_PARAMETER>NONE</INPUT_PARAMETER>
            <RETURN_PARAMETER>System.Data.DataSet</RETURN_PARAMETER>
        </WMS_METHOD>
        <WMS_METHOD>
             <ID>2</ID>
            <METHOD>SendTask</METHOD>   
            <INPUT_PARAMETER>System.Data.DataSet</INPUT_PARAMETER>
            <RETURN_PARAMETER>NONE</RETURN_PARAMETER>
        </WMS_METHOD>
    </WMS>
</WMS_MODULE>

三.动态加载模块部分的类图

iOS 动态加载Framework 动态加载技术_System

数据类型:

◎DataSet:数据集

◎List<IModule>:IMoudle对象的列表

接口:

◎ISystemProxy:代理对象的接口
◎IModule:具体实现对象的接口
对象:
◎XmlConfiguration:配置文件对象,加载配置文件信息
◎WMSProxy:上位系统(WMS)接口模块的访问代理对象
◎MISProxy:上位系统(MIS)系统接口模块的访问代理对象
◎ContreteWMSModule:上位系统(WMS)模块的具体访问者
◎WMSModule1-N:与上位系统(WMS)接口的具体实现
 
四.动态加载模块技术的核心代码
1.       接口部分
1.1  IModule接口
 
 
 
1. /// <summary>  
2. /// 具体实现模块对象的接口  
3. /// </summary>  
4. public interface
5.     {

6. /// <summary>  
7. /// 从WMS上取任务单列表,  
8. /// 无论任务单格式是什么都  
9. /// 转换成数据集的形式返回。  
10. /// </summary>  
11. /// <returns></returns>  
12.         System.Data.DataSet GetDataFromWMS();
13. /// <summary>  
14. /// 发送数据到WMS上  
15. /// </summary>  
16. /// <param name="dsData">数据流集合</param>  
17. void
18. /// <summary>  
19. /// 将任务单数据解析成DataSet表集合  
20. /// </summary>  
21. /// <param name="strData">数据流</param>  
22. /// <returns>解析后的表集合</returns>  
23. string
24.       
25.         }
26. 
 
 
1.2   ISystemProxy接口
 
   
 
1. /// <summary> 
2. /// WMS访问代理接口 
3. /// 所有WMS访问代理对象 
4. /// 均需要实现该接口 
5. /// </summary> 
6. public interface
7.     {

8. /// <summary> 
9. /// 注册对象具体WMS访问模块对象 
10. /// </summary> 
11. /// <param name="Proxy">具体的WMS访问者</param> 
12. void
13. /// <summary> 
14. /// 获取任务列表 
15. /// </summary> 
16. /// <param name=’strId’>模块ID</param> 
17. /// <returns>返回一个表集合</returns> 
18. string
19.      }
 
   
 
1.       对象
2.1   ContreteWMSModule对象
 
 
1. /// <summary> 
2. /// 上位系统模块具体的访问者 
3. /// </summary> 
4. public class
5.     {

6. 
7. protected DCS_Configuration.Struct.TagWmsModule stModule = null; //配置文件中解析的配置项对象 
8. 
9.         #region 接口 
10. 
11. public virtual
12.         {

13. //调用反射方法 
14. new object[0]);    //取数据,并保存为字符串 
15.           
16. //返回数据集 
17. return
18.         }
19. 
20. public virtual void
21. 
22.         #endregion 
23. 
24. 
25. 
26.       
27.         #region 构造器 
28. /// <summary> 
29. /// 构造器 
30. /// </summary> 
31. /// <param name="stModule">具体访问者对应的配置信息</param> 
32. public
33.         {

34. this.stModule = stModule;
35. 
36. //初始化反射信息 
37.         } 
38.         #endregion 
39. 
40. 
41. 
42. 
43. 
44.         #region 反射构建对象 
45. protected object objClass = null;       //类对象 
46. protected Type type = null;             //对象类型 
47. protected System.Reflection.MethodInfo methodGetDataFromWMS = null;   //反射方法 
48. protected System.Reflection.MethodInfo methodSendDataToWMS = null;   //反射方法 
49. protected System.Reflection.MethodInfo methodAnalysis = null;   //反射方法 
50. 
51. 
52. /// <summary> 
53. /// 初始化反射信息 
54. /// </summary> 
55. protected void
56.         {

57.             System.Reflection.Assembly assembly =
58.                 System.Reflection.Assembly.LoadFrom(stModule.Path);
59. 
60. //反射出对象 
61. "."
62. 
63. //反射除类型 
64.             type = objClass.GetType();
65. 
66. //反射出方法 
67. "GetTask");
68. "SendTask");
69. "Analysis");
70.             
71.         } 
72.         #endregion 
73. 
74. 
75. }
76. 
 
 
2.2 WMSProxy
 
   
 
/// <summary>
    /// 具体代理类
    /// </summary>
    public class WMSProxy:ISystemProxy
    {
        private List<WmsProxy.WmsModule.IWMSModule> visitors = new List<WmsProxy.WmsModule.IWMSModule>();       //具体访问者列表
 
        #region 接口
 
        /// <summary>
        /// 获取已经注册的模块
        /// </summary>        
        public List<WmsProxy.WmsModule.IWMSModule> RegisitedModules
        {
            get { return visitors; }
            
        }
 
        /// <summary>
        /// 注册访问模块列表
        /// </summary>
        /// <param name="visitor">具体WMS访问模块</param>
        public void Regisiter(WmsProxy.WmsModule.IWMSModule visitor) 
        {
            visitors.Add(visitor);
            return;
        }
        /// <summary>
        /// 获取任务列表
        /// </summary>
        /// <param name="strID">WMS访问模块对应的ID</param>
        /// <returns></returns>
        public System.Data.DataSet GetTaskList(string strID)
        {
            System.Data.DataSet ds = new System.Data.DataSet();
 
            WmsProxy.WmsModule.ContreteModule visitor = GetVisitorByID(strID);
 
            ds=visitor.GetDataFromWMS();
 
            return ds;
        }
 
 
        /// <summary>
        /// 根据ID查找对应模块
        /// </summary>
        /// <param name="strID"></param>
        /// <returns></returns>
        private WmsProxy.WmsModule.ContreteModule GetVisitorByID(string strID) 
        {
            foreach (WmsModule.ContreteModule visitor in visitors)     //遍历所有对象
            {
                if (visitor.Id.CompareTo(strID) == 0)    //找到该对象
                {
                    return visitor;
                }
            }
            
            //未找到ID对应的注册对象
            DCSException.UnknowException err =
                new DCSException.UnknowException("未找到ID对应的注册对象", "GetVisitorByID", DCSException.ErrCode.ERR_NOT_FIND_OBJECT_WITH_ID);
            throw (err);
            
            
}