You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

114 lines
3.7 KiB

2 years ago
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Reflection;
  5. namespace EasyBL.DllDynamicCall
  6. {
  7. public class DllCall
  8. {
  9. private Assembly _assembly;
  10. public Dictionary<string, object> Objects { get; set; }
  11. public Dictionary<string, Dictionary<string, MethodInfo>> Methods { get; set; }
  12. /// <summary>
  13. /// 构造器
  14. /// </summary>
  15. /// <param name="dllPath">DLL绝对路径</param>
  16. public DllCall(string dllPath)
  17. {
  18. LoadDll(dllPath);
  19. Objects = new Dictionary<string, object>();
  20. Methods = new Dictionary<string, Dictionary<string, MethodInfo>>();
  21. }
  22. #region 公开方法
  23. /// <summary>
  24. /// 注册要目标类
  25. /// </summary>
  26. /// <param name="classFullName">类的完全限定名</param>
  27. /// <param name="objectName">指定的对象名</param>
  28. /// <param name="constructorParaTypes">构造器参数类型</param>
  29. /// <param name="constructorParas">构造器参数</param>
  30. public void RegisterObject(string classFullName, string objectName, Type[] constructorParaTypes, object[] constructorParas)
  31. {
  32. var t = _assembly.GetType(classFullName, true, false);
  33. var constructorInfo = t.GetConstructor(constructorParaTypes);
  34. if (constructorInfo != null)
  35. {
  36. var targetObject = constructorInfo.Invoke(constructorParas);
  37. if (!Objects.ContainsKey(objectName))
  38. {
  39. Objects.Add(objectName, targetObject);
  40. }
  41. if (!Methods.ContainsKey(objectName))
  42. {
  43. Methods.Add(objectName, new Dictionary<string, MethodInfo>());
  44. }
  45. }
  46. }
  47. /// <summary>
  48. /// 注册函数
  49. /// </summary>
  50. /// <param name="classFullName">类完全限定名</param>
  51. /// <param name="objectName">制定函数所在对象名</param>
  52. /// <param name="funcName">函数名</param>
  53. public void RegisterFunc(string classFullName, string objectName, string funcName)
  54. {
  55. var t = _assembly.GetType(classFullName, true, false);
  56. var method = t.GetMethod(funcName);
  57. if (Methods.ContainsKey(objectName))
  58. {
  59. if (!Methods[objectName].ContainsKey(funcName))
  60. {
  61. Methods[objectName].Add(funcName, method);
  62. }
  63. }
  64. }
  65. /// <summary>
  66. /// 调用函数
  67. /// </summary>
  68. /// <param name="objectName">目标对象名</param>
  69. /// <param name="funcName">函数名</param>
  70. /// <param name="paras">参数表,没有参数则用null</param>
  71. /// <returns></returns>
  72. public object CallFunc(string objectName, string funcName, object[] paras)
  73. {
  74. var targetObjec = Methods[objectName];
  75. var targetFunc = targetObjec[funcName];
  76. const BindingFlags flag = BindingFlags.Public | BindingFlags.Instance;
  77. var result = targetFunc.Invoke(Objects[objectName], flag, Type.DefaultBinder, paras, null);
  78. return result;
  79. }
  80. #endregion 公开方法
  81. #region 私有方法
  82. /// <summary>
  83. /// 加载DLL
  84. /// </summary>
  85. /// <param name="dllPath">DLL绝对路径</param>
  86. private void LoadDll(string dllPath)
  87. {
  88. if (File.Exists(dllPath))
  89. {
  90. _assembly = Assembly.LoadFrom(dllPath);
  91. }
  92. else
  93. {
  94. throw new FileNotFoundException($"{dllPath} isn't exist!");
  95. }
  96. }
  97. #endregion 私有方法
  98. }
  99. }