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,以表示是否成功加载了测试方案。

相关推荐
唐青枫12 小时前
别只会看日志:C#.NET SOS 调试扩展从 Dump 到内存泄漏排查
c#·.net
yswenli19 小时前
基于C#开发网站视频嗅探下载工具——BrowserVideoGrabber
c#·videodownload·webvideodownload·videograbber
Lost of 程序猿19 小时前
M2 实战:询价与采购订单聚合落地——跨聚合一致性、领域事件与 Outbox
开发语言·c#·asp.net·.net
Polevne21 小时前
C# GRPC 一元与双向流
linux·算法·c#
XiaoZhenHua982 天前
C#工业机器视觉Recipe配方系统设计:多型号、多相机、多工位参数如何统一管理
c#·软件架构·机器视觉·工业自动化·工业软件·recipe
fujisheng6612 天前
FUI 导航实践:拆开 Layer、History、Coverage 与 Cache 的组合语义
c#·unity3d
淡海水2 天前
10-05-高级-模式匹配-CSharp如何改变与数据结构的交互方式
数据结构·算法·c#·模式匹配
XiaoZhenHua982 天前
C# WinForms + 西门子S7 + SQLite + EPPlus生产数据采集系统架构设计
系统架构·sqlite·c#
Lost of 程序猿2 天前
船岸数据同步链路实战:SendFlag、单调版本号与断网三天后的续传
后端·c#·asp.net
cjp5603 天前
012.UG二次开发,UG管道服务器与WPF管道通讯,传输JSON数据
c#