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

相关推荐
BIGFISH201911 小时前
上下相机引导贴合的标定(绝对坐标方式)
c#
燃尽了,可无15 小时前
C#基础编程核心知识点总结
开发语言·c#
我不是程序猿儿18 小时前
【C#】观察者模式 + UI 线程调度、委托讲解
观察者模式·ui·c#
专注VB编程开发20年18 小时前
c# .net支持 NativeAOT 或 Trimming 的库是什么原理
前端·javascript·c#·.net
钢铁男儿18 小时前
C# 简单工厂模式(简单工厂模式如何工作)
前端·c#·简单工厂模式
isyoungboy21 小时前
c#实现鼠标mousemove事件抽稀,避免大数据阻塞网络
c#·计算机外设·远程桌面·deskflow
一枚小小程序员哈1 天前
基于asp.net 的在线餐饮订餐系统的设计与实现/基于c#的网上订餐系统/餐厅管理系统
后端·c#·asp.net
好望角雾眠1 天前
第三阶段数据库-7:sql中函数,运算符,常用关键字
数据库·笔记·sql·学习·sqlserver·c#
海绵宝宝汉堡包1 天前
c# 项目 文件夹
开发语言·c#
曹牧1 天前
C#:窗体间传值
c#