動態加載dll,擴展系統功能

動態加載dll,主要是爲了擴展功能,加強靈活性而實現的。主要經過xml配置,來獲取全部要動態加載的dll,而後經過反射機制來調用dll中的類及其方法。編程


研究了一天,小有所得,寫了一個簡單的動態加載dll的通用模塊,拿出來與你們分享一下:c#


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace DynamicLoadDLL
{
    /// <summary>
    /// 動態加載dll
    /// </summary>
    public class LoadDLL
    {
        private Assembly ass = null;

        /// <summary>
        /// 加載dll
        /// </summary>
        /// <param name="dllPath">dll文件路徑</param>
        public LoadDLL(string dllPath)
        {
            this.ass = Assembly.LoadFrom(dllPath);                     //利用dll的路徑加載(fullname)
        }

        /// <summary>
        /// 返回反射的dll
        /// </summary>
        /// <returns></returns>
        public Assembly GetAssembly()
        {
            return this.ass;
        }

        /// <summary>
        /// 獲取全部類名
        /// </summary>
        /// <returns></returns>
        public Type[] GetClass()
        {
            return ass.GetTypes();
        }

        /// <summary>
        /// 獲取程序集下的全部文件名
        /// </summary>
        /// <returns></returns>
        public Module[] GetModules()
        {
            return ass.GetModules();            
        }

        /// <summary>
        /// 獲取程序集清單文件表中的文件
        /// </summary>
        /// <returns></returns>
        public FileStream[] GetFiles()
        {
            return ass.GetFiles();
        }

    }
}

這個是加載dll的,而後返回一個Assembly類型的一個反射值,若是該dll中有多個命名空間和類的話,就只用一個 Assembly類型的一個反射值便可以完成調用,不然每次生成一個類,都須要反射一次。IO操做相對而言是比較耗費CPU,影響效率的。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace DynamicLoadDLL
{
    /// <summary>
    /// 加載類
    /// </summary>
    public class LoadClass
    {
        private static LoadClass dlc = null;
        private Type type;
        private object obj = null;                                         //實例

        /// <summary>
        /// 加載dll
        /// </summary>
        /// <param name="ass">dll引用</param>
        /// <param name="nameSpace">類的命名空間</param>
        /// <param name="classPath">類名稱</param>
        private LoadClass(Assembly ass, string nameSpace, string classPath)
        {
            //加載dll後,須要使用dll中某類.
            type = ass.GetType(nameSpace + "." + classPath);                                //利用類型的命名空間和名稱得到類型

            //須要實例化類型,才能夠使用,參數能夠人爲的指定,也能夠無參數,靜態實例能夠省略
            obj = Activator.CreateInstance(type);                         //利用指定的參數實例話類型

        }

        /// <summary>
        /// 加載dll
        /// </summary>
        /// <param name="ass">dll引用</param>
        /// <param name="nameSpace">類的命名空間</param>
        /// <param name="classPath">類名稱</param>
        public static LoadClass GetInstance(Assembly ass, string nameSpace, string classPath)
        {
            if (dlc == null)
            {
                dlc = new LoadClass(ass, nameSpace, classPath);
            }
            return dlc;
        }

        /// <summary>
        /// 獲取屬性集
        /// </summary>
        /// <returns>返回屬性值</returns>
        public PropertyInfo[] GetAttrs()
        {
            //調用類型中的某個屬性:
            PropertyInfo[] prop = type.GetProperties();                //經過屬性名稱得到屬性

            //返回屬性集
            return prop;
        }

        public MethodInfo[] GetMethods()
        {
            //調用類型中的方法:
            MethodInfo[] method = type.GetMethods(BindingFlags.NonPublic);                //得到方法集

            //返回方法集
            return method;
        }


        /// <summary>
        /// 獲取屬性值
        /// </summary>
        /// <param name="attrName">屬性名稱</param>
        /// <returns>返回屬性值</returns>
        public object GetAttrValue(string attrName)
        {
            //調用類型中的某個屬性:
            PropertyInfo prop = type.GetProperty(attrName);                //經過屬性名稱得到屬性

            //返回屬性值
            return prop.GetValue(obj);
        }

        /// <summary>
        /// 設置屬性值
        /// </summary>
        /// <param name="attrName">屬性名稱</param>
        /// <returns>返回屬性值</returns>
        public void SetAttrValue(string attrName, string attrValue)
        {
            //調用類型中的某個屬性:
            PropertyInfo prop = type.GetProperty(attrName);                //經過屬性名稱得到屬性

            //返回屬性值
            prop.SetValue(obj, attrValue);
        }

        /// <summary>
        /// 執行類方法
        /// </summary>
        /// <param name="methodName">方法名稱</param>
        /// <param name="paras">參數</param>
        /// <param name="types">參數類型</param>
        /// <returns></returns>
        public object GetMethod(string methodName, object[] paras,Type[] types)
        {
            
            //調用類型中的某個方法:
            MethodInfo method = type.GetMethod(methodName,types);                //經過方法名稱得到方法

            //執行方法
            return method.Invoke(obj, paras);
        }
    }
}

上面這個類根據dll反射值,命名空間和類名,反射出一個具體的類,還提供了屬性和方法的調用方法。很方便。


這些是我在研究插件編程時,順帶研究的,不太深刻,但但願對你能有所幫助。this


版權聲明:本文爲博主原創文章,未經博主容許不得轉載。spa

相關文章
相關標籤/搜索