使用反射的方法加载DLL

公司内部的接口走的是WCF,接口使用功能号调用的方式。

定义了WPFunction(方法),WPFunctionModule(方法模块),FunctionManager(方法管理类)管理方法,通过反射的方式加载DLL到FunctionManager,调用的时候通过WPFunction GetFuncByID(string funid)得到方法。

注意: Assembly asm = Assembly.Load(b);的方式dll加载到内存就会被释放掉,Assembly asm = Assembly.LoadFile(fileName);的方式dll则会一直被占用。

其它实现如下:

WPFunction

  1     public class WPFunction
  2     {
  3         private string FFunID = "";         //函数标识
  4         private string FClsID = "";         //所属函数类
  5         private string FFunDesc = "";       //函数简述
  6 
  7         private string FDllName = "";       //Dll文件名称
  8         private string FFunName = "";       //函数名称
  9 
 10         private System.Reflection.Assembly FAsmbly = null;  //载入Dll的Assembly
 11         private string FObjName = "";   //调用的类的名称(包括命名空间)
 12         private Type FObjType = null;   //调用的类类型
 13         private object FObjInstance = null; //调用的类的实例
 14 
 15         private MethodInfo FFunInfo = null; //函数信息
 16         private bool FIsFunLoaded = false;
 17         private WPFunctionModule FFunModule = null;
 18         
 19         public WPFunction(WPFunctionModule fmodule, string fid,string funname, string desc, Type tp)
 20         {
 21             FunModule = fmodule;
 22             FunID = fid;
 23             FunDesc = desc;
 24             ObjType = tp;
 25             FunInfo = tp.GetMethod(funname);
 26         }
 27 
 28         [DefaultValue("")]
 29         public string FunID
 30         {
 31             get { return FFunID; }
 32             set { FFunID = value; }
 33         }
 34 
 35         [DefaultValue("")]
 36         public string ClsID
 37         {
 38             get { return FClsID; }
 39             set { FClsID = value; }
 40         }
 41 
 42         [DefaultValue("")]
 43         public string FunDesc
 44         {
 45             get { return FFunDesc; }
 46             set { FFunDesc = value; }
 47         }
 48 
 49         [DefaultValue("")]
 50         public string DllName
 51         {
 52             get { return FDllName; }
 53             set { FDllName = value; }
 54         }
 55 
 56         [DefaultValue("")]
 57         public string FunName
 58         {
 59             get { return FFunName; }
 60             set { FFunName = value; }
 61         }
 62 
 63         [DefaultValue(null)]
 64         public System.Reflection.Assembly Asmbly
 65         {
 66             get { return FAsmbly; }
 67             set { FAsmbly = value; }
 68         }
 69 
 70         [DefaultValue("")]
 71         public string ObjName
 72         {
 73             get { return FObjName; }
 74             set { FObjName = value; }
 75         }
 76 
 77         [DefaultValue(null)]
 78         public Type ObjType
 79         {
 80             get { return FObjType; }
 81             set { FObjType = value; }
 82         }
 83 
 84         [DefaultValue(null)]
 85         public object ObjInstance
 86         {
 87             get { return FObjInstance; }
 88             set { FObjInstance = value; }
 89         }
 90 
 91         [DefaultValue(null)]
 92         public MethodInfo FunInfo
 93         {
 94             get { return FFunInfo; }
 95             set { FFunInfo = value; }
 96         }
 97 
 98         [DefaultValue(false)]
 99         public bool IsFunLoaded
100         {
101             get { return FIsFunLoaded; }
102             set { FIsFunLoaded = value; }
103         }
104 
105         [DefaultValue(null)]
106         public WPFunctionModule FunModule
107         {
108             get { return FFunModule; }
109             set { FFunModule = value; }
110         }
111     }

WPFunctionModule:

 1     public class WPFunctionModule
 2     {
 3         public string DllName;
 4         public string DllDesc;
 5         public List<WPFunction> Functions;
 6 
 7         public WPFunctionModule(string name, string desc)
 8         {
 9             DllName = name;
10             DllDesc = desc;
11             Functions = new List<WPFunction>();
12         }
13 
14         private bool IsFunctionReg(string funid)
15         {
16             int i;
17             for (i = 0; i < Functions.Count; i++)
18                 if (Functions[i].FunID == funid)
19                     return true;
20             return false;
21         }
22 
23         public void RegisterFunction(string funid,string funname, string desc, Type tp)
24         {
25             if (!IsFunctionReg(funid))
26                 Functions.Add(new WPFunction(this, funid, funname, desc, tp));
27         }
28     }

FunctionManager:

  1     /// <summary>
  2     /// 管理中间件功能管理类
  3     /// </summary>
  4     public static class FunctionManager
  5     {
  6         public static Dictionary<string, string> FunctionKeyValueDic = new Dictionary<string, string>();
  7 
  8         public static List<WPFunctionModule> Modules = new List<WPFunctionModule>();
  9 
 10         /// <summary>
 11         /// 查找窗体
 12         /// </summary>
 13         public static WPFunction FindFunc(string funid)
 14         {
 15             foreach (WPFunctionModule md in Modules)
 16             {
 17                 WPFunction fun = md.Functions.Find(delegate(WPFunction f) { return f.FunID == funid; });
 18                 if (fun != null)
 19                     return fun;
 20             }
 21             return null;
 22         }
 23 
 24         /// <summary>
 25         /// 加载方法
 26         /// </summary>
 27         /// <param name="fun"></param>
 28         public static void LoadFunc(WPFunction fun)
 29         {
 30             if (!IsInstanced(fun))
 31             {
 32                 try
 33                 {
 34                     fun.ObjInstance = Activator.CreateInstance(fun.ObjType);
 35                     fun.IsFunLoaded = true;
 36                 }
 37                 catch
 38                 {
 39 
 40                 }
 41             }
 42         }
 43 
 44         /// <summary>
 45         /// 根据ID获得方法
 46         /// </summary>
 47         public static WPFunction GetFuncByID(string funid)
 48         {
 49             WPFunction fun = FindFunc(funid);
 50             if (fun == null) return null;
 51 
 52             if (!fun.IsFunLoaded) LoadFunc(fun);
 53             return fun;
 54         }
 55 
 56         /// <summary>
 57         /// 方法数量
 58         /// </summary>
 59         /// <returns></returns>
 60         public static int FunctionCount()
 61         {
 62             int cnt = 0;
 63             foreach (WPFunctionModule md in Modules)
 64             {
 65                 cnt += md.Functions.Count();
 66             }
 67             return cnt;
 68         }
 69 
 70         /// <summary>
 71         /// 查找类是否创建
 72         /// </summary>
 73         /// <param name="fun"></param>
 74         /// <returns></returns>
 75         public static bool IsInstanced(WPFunction fun)
 76         {
 77             foreach (WPFunction f in fun.FunModule.Functions)
 78             {
 79                 if ((f.IsFunLoaded) && (f.ObjType == fun.ObjType))
 80                 {
 81                     fun.ObjInstance = f.ObjInstance;
 82                     return true;
 83                 }
 84             }
 85             return false;
 86         }
 87 
 88         /// <summary>
 89         /// 增加模块
 90         /// </summary>
 91         static void AddModule(WPFunctionModule module)
 92         {
 93             if (Modules.IndexOf(module) < 0)
 94             {
 95                 Modules.Add(module);
 96                 module.Functions.Sort(delegate(WPFunction f1, WPFunction f2) { return Comparer<string>.Default.Compare(f1.FunID, f2.FunID); });
 97             }
 98         }
 99 
100         public static bool IsSubTypeOf(this Type objType, Type baseType)
101         {
102             if (objType == null) return false;
103             if (baseType == null) return false;
104 
105             // 基类型不是接口
106             if (!baseType.IsInterface)
107             {
108                 return objType.IsSubclassOf(baseType);
109             }
110             else // 基类型是接口
111             {
112                 return objType.GetInterfaces().Where(tp => tp == baseType).Any();
113             }
114         }
115 
116         /// <summary>
117         /// 加载功能方法
118         /// </summary>
119         public static void LoadFunctions()
120         {
121             try
122             {
123                 Modules.Clear();
124                 //string[] files = Directory.GetFiles(@System.Windows.Forms.Application.StartupPath + "\bin", "mngfunc_*.dll");
125                 string[] files = Directory.GetFiles(@System.AppDomain.CurrentDomain.BaseDirectory + "\bin", "mngfunc_*.dll");
126                 foreach (string fileName in files)
127                 {
128                     try
129                     {
130                         byte[] b = File.ReadAllBytes(fileName);
131                         Assembly asm = Assembly.Load(b);
132                         //Assembly asm = Assembly.LoadFile(fileName);
133 
134                         if (asm != null)
135                         {
136                             var query = (from tp in asm.GetTypes()
137                                          where tp.IsSubTypeOf(typeof(IWPFunctionBuilder))
138                                          select tp).ToArray();
139 
140                             foreach (var tp in query)
141                             {
142                                 var obj = Activator.CreateInstance(tp) as IWPFunctionBuilder;
143                                 AddModule(obj.GetModule());
144                             }
145                         }
146                     }
147                     catch { }
148                 }
149             }
150             catch (Exception ex)
151             {
152                 Console.WriteLine(ex.Message);
153             }
154         }
155     }
原文地址:https://www.cnblogs.com/CarlBlogs/p/7404882.html