c# 动态加载模块插件示例

csharp 复制代码
public static class TestManager
{
    static string dllPath = "./TestServices.dll";

    static Dictionary<string, ITest> TestScheme = new Dictionary<string, ITest>();

    static public ITest CurrentTest = null;

    static public void Load()
    {
        if (!File.Exists(dllPath))
        {
            isEnable = false;
            return;
        }

        TestScheme.Clear();

        var dllAssembly = Assembly.LoadFrom(dllPath);

        var types = dllAssembly.GetTypes()
                               .Where(x => x.GetInterface("ITest") != null);

        foreach (Type type in types)
        {
            var attributes = type.GetCustomAttributes<TestAttribute>(false);

            if (attributes.Count() <= 0)
            {
                continue;
            }

            TestAttribute testAttr = attributes.ElementAt(0);

            if (testAttr.Tools.Contains(GCH.CurTool))
            {
                var instance = (ITest)Activator.CreateInstance(type);
                TestScheme.Add(type.Name, instance);
            }
        }

        if (TestScheme.Count > 0)
        {
            isEnable = true;
        }
    }
}

代码结构分析:

  1. 类定义和成员变量

    • TestManager 是一个静态类,包含了一些静态成员变量和静态方法。
    • dllPath:存储了一个相对路径 "./TestServices.dll",表示要加载的 DLL 文件的位置。使用相对路径可能会导致在不同的工作目录下出现问题,因为相对路径是相对于程序的启动目录的。
    • TestScheme:一个静态的 Dictionary<string, ITest> 类型的字典,用于存储根据一定条件筛选出来的测试方案,其中键是类型的名称,值是实现了 ITest 接口的对象实例。
    • CurrentTest:一个静态的 ITest 类型的对象,初始化为 null,从代码来看,它可能是用于存储当前正在使用的测试对象,但在提供的代码中未看到其使用或赋值逻辑,可能是代码不完整或者尚未实现相应功能。
    • Load:一个静态方法,用于加载测试相关的内容。
  2. Load 方法的详细分析

    • 文件存在性检查

      csharp 复制代码
      if (!File.Exists(dllPath))
      {
          isEnable = false;
          return;
      }

      首先检查 dllPath 指向的文件是否存在,如果不存在,将 isEnable (未在代码中声明,会导致编译错误)设置为 false 并返回,结束方法执行。这里可能遗漏了 isEnable 的声明。

    • 清空字典

      csharp 复制代码
      TestScheme.Clear();

      清空 TestScheme 字典,以确保在重新加载时不会残留之前的数据。

    • 程序集加载和类型筛选

      csharp 复制代码
      var dllAssembly = Assembly.LoadFrom(dllPath);
      var types = dllAssembly.GetTypes().Where(x => x.GetInterface("ITest")!= null);
      • 使用 Assembly.LoadFrom 从指定的 DLL 路径加载程序集。
      • 通过 GetTypes 获取程序集中的所有类型,并使用 Where 筛选出实现了 ITest 接口的类型。
    • 属性检查和实例创建

      csharp 复制代码
      foreach (Type type in types)
      {
          var attributes = type.GetCustomAttributes<TestAttribute>(false);
          if (attributes.Count() <= 0)
          {
              continue;
          }
          TestAttribute testAttr = attributes.ElementAt(0);
          if (testAttr.Tools.Contains(GCH.CurTool))
          {
              var instance = (ITest)Activator.CreateInstance(type);
              TestScheme.Add(type.Name, instance);
          }
      }
      • 对于筛选出来的每个类型,使用 GetCustomAttributes<TestAttribute>(false) 获取该类型的 TestAttribute 集合。
      • 如果 TestAttribute 集合的元素数量小于等于 0,使用 continue 跳过该类型。
      • TestAttribute 集合的第一个元素(使用 ElementAt(0),如果集合为空,会引发异常)。
      • 检查 TestAttributeTools 属性是否包含 GCH.CurTool,如果包含,使用 Activator.CreateInstance 创建该类型的实例,并添加到 TestScheme 字典中,键为类型的名称。
    • 启用状态设置

      csharp 复制代码
      if (TestScheme.Count > 0)
      {
          isEnable = true;
      }

      根据 TestScheme 字典中的元素数量,将 isEnable (未声明)设置为 true 或保持为 false,以表示是否成功加载了测试方案。

相关推荐
pchmi4 小时前
CNN常用卷积核
深度学习·神经网络·机器学习·cnn·c#
yuanpan4 小时前
23种设计模式之《组合模式(Composite)》在c#中的应用及理解
开发语言·设计模式·c#·组合模式
滴_咕噜咕噜5 小时前
C#基础总结:常用的数据结构
开发语言·数据结构·c#
万兴丶8 小时前
Unity 适用于单机游戏的红点系统(前缀树 | 数据结构 | 设计模式 | 算法 | 含源码)
数据结构·unity·设计模式·c#
程序猿多布10 小时前
C#设计模式 学习笔记
设计模式·c#
软件黑马王子16 小时前
Unity游戏制作中的C#基础(5)条件语句和循环语句知识点全解析
游戏·unity·c#
shepherd枸杞泡茶16 小时前
第3章 3.3日志 .NET Core日志 NLog使用教程
c#·asp.net·.net·.netcore
Aimeast1 天前
关于选择最佳.NET Core SSH服务器库的全面分析
c#·ssh
蒋劲豪1 天前
WPF项目暴露WebApi接口;WinForm项目暴露WebApi接口;C#项目暴露WebApi接口;
开发语言·c#·wpf
code bean1 天前
【C# 数据结构】队列 FIFO
开发语言·数据结构·c#