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

相关推荐
小老鼠爱大米1 小时前
C# WPF - Prism 学习篇:搭建项目(一)
c#·wpf·prism
小码编匠5 小时前
WPF 自定义分页控件,可通过样式模板修改外观
后端·c#·.net
CoderPractice6 小时前
C#控制台小项目-飞行棋
开发语言·c#·小游戏·飞行棋
ajassi20007 小时前
开源 C# .net mvc 开发(八)IIS Express轻量化Web服务器的配置和使用
linux·开源·c#·mvc·.net
19H12 小时前
Flink-Source算子状态恢复分析
c#·linq
枯萎穿心攻击14 小时前
响应式编程入门教程第二节:构建 ObservableProperty<T> — 封装 ReactiveProperty 的高级用法
开发语言·unity·c#·游戏引擎
Eiceblue16 小时前
【免费.NET方案】CSV到PDF与DataTable的快速转换
开发语言·pdf·c#·.net
昏睡红猹1 天前
C#脚本化(Roslyn):如何在运行时引入nuget包
c#
张人玉1 天前
C# 常量与变量
java·算法·c#