模块动态加载技术

来源:互联网 发布:捕鱼软件开发 编辑:程序博客网 时间:2024/04/29 10:36

 

考察如下应用:

 

 

 

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

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

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

 

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

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

 

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

数据类型:

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 IModule
  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 SendDataToWMS(System.Data.DataSet dsData); 
  18.         /// <summary> 
  19.         /// 将任务单数据解析成DataSet表集合 
  20.         /// </summary> 
  21.         /// <param name="strData">数据流</param> 
  22.         /// <returns>解析后的表集合</returns> 
  23.         System.Data.DataSet Analysis(string strData);
  24.       
  25.         }

 

1.2   ISystemProxy接口

  1. /// <summary>
  2.     /// WMS访问代理接口
  3.     /// 所有WMS访问代理对象
  4.     /// 均需要实现该接口
  5.     /// </summary>
  6.     public interface ISystemProxy
  7.     {
  8.         /// <summary>
  9.         /// 注册对象具体WMS访问模块对象
  10.         /// </summary>
  11.         /// <param name="Proxy">具体的WMS访问者</param>
  12.         void Regisiter(WmsProxy.WmsModule.IWMSModule Proxy);       
  13.         /// <summary>
  14.         /// 获取任务列表
  15.         /// </summary>
  16.         /// <param name=’strId’>模块ID</param>
  17.         /// <returns>返回一个表集合</returns>
  18.         System.Data.DataSet GetTaskList(string strId);
  19.      }

1.       对象

2.1   ContreteWMSModule对象

  1.   /// <summary>
  2.     /// 上位系统模块具体的访问者
  3.     /// </summary>
  4.     public class ContreteWMSModule:IModule
  5.     {
  6.   protected DCS_Configuration.Struct.TagWmsModule stModule = null//配置文件中解析的配置项对象
  7.         #region 接口
  8.         public virtual System.Data.DataSet GetDataFromWMS() 
  9.         {
  10.             //调用反射方法
  11.             System.Data.DataSet ds = (System.Data.DataSet)methodGetDataFromWMS.Invoke(objClass, new object[0]);    //取数据,并保存为字符串
  12.           
  13.             //返回数据集
  14.             return ds;
  15.         }
  16.         public virtual void SendDataToWMS(System.Data.DataSet ds) { }
  17.         #endregion
  18.       
  19.         #region 构造器
  20.         /// <summary>
  21.         /// 构造器
  22.         /// </summary>
  23.         /// <param name="stModule">具体访问者对应的配置信息</param>
  24.         public ContreteWMSModule(DCS_Configuration.Struct.TagWmsModule stModule)
  25.         {
  26.             this.stModule = stModule;
  27.             InitReflection();       //初始化反射信息
  28.         }
  29.         #endregion
  30.         #region 反射构建对象
  31.         protected object objClass = null;       //类对象
  32.         protected Type type = null;             //对象类型
  33.         protected System.Reflection.MethodInfo methodGetDataFromWMS = null;   //反射方法
  34.         protected System.Reflection.MethodInfo methodSendDataToWMS = null;   //反射方法
  35.         protected System.Reflection.MethodInfo methodAnalysis = null;   //反射方法
  36.         /// <summary>
  37.         /// 初始化反射信息
  38.         /// </summary>
  39.         protected void InitReflection()     
  40.         {
  41.             System.Reflection.Assembly assembly =
  42.                 System.Reflection.Assembly.LoadFrom(stModule.Path);
  43.             //反射出对象
  44.             objClass = assembly.CreateInstance(stModule.AssemblyName + "." + stModule.ClassName);
  45.             //反射除类型
  46.             type = objClass.GetType();
  47.             //反射出方法
  48.             methodGetDataFromWMS = type.GetMethod("GetTask");
  49.             methodSendDataToWMS = type.GetMethod("SendTask");
  50.             methodAnalysis = type.GetMethod("Analysis");
  51.             
  52.         }
  53.         #endregion
  54. }

 

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

           

           

}

 

 

QQ:819543772

EMail:wuchunlei@163.com