AssemblyManager 程序集管理器

news2024/11/24 13:06:42

AssemblyManager 程序集管理器

程序执行中使用反射对框架的搭建有着强大的影响,如何管理程序集方便使用反射获取类型操作对象是本文章的重点

1.AssemblyInfo

对于一个程序集这里使用一个AssemblyInfo对象进行管理

  • Assembly :对应的程序集
  • AssemblyTypeList :该程序集中所有对象的类型(包括接口、抽象类等)
  • AssemblyTypeGroupList :一个key对应多个值的字典存储对应的接口对应的派生类(Key:某个接口类型,Value:继承这个接口的类对象类型)
        public Assembly Assembly { get; private set; }
        public readonly List<Type> AssemblyTypeList = new List<Type>();
        public readonly OneToManyList<Type, Type> AssemblyTypeGroupList = new OneToManyList<Type, Type>();

完整的AssemblyInfo代码

    public sealed class AssemblyInfo
    {
        public Assembly Assembly { get; private set; }
        public readonly List<Type> AssemblyTypeList = new List<Type>();
        public readonly OneToManyList<Type, Type> AssemblyTypeGroupList = new OneToManyList<Type, Type>();

        public void Load(Assembly assembly)
        {
            Assembly = assembly;
            Type[] assemblyTypes = Assembly.GetTypes();
            foreach (Type type in assemblyTypes) 
            {
                if (type.IsAbstract || type.IsInterface)
                    continue;
                Type[] interfaces = type.GetInterfaces();
                foreach (Type interfaceType in interfaces)
                {
                    AssemblyTypeGroupList.Add(interfaceType, type);
                }
            }
            AssemblyTypeList.AddRange(assemblyTypes);
        }

        public void UnLoad()
        {
            AssemblyTypeList.Clear();
            AssemblyTypeGroupList.Clear();
        }
    }

2.AssemblyManager

三个事件(加载某个程序集事件、卸载某个程序集事件、重新加载某个程序集事件)
字典对应的是程序集名称(使用int)对应的程序集信息AssemblyInfo

        public static event Action<int> OnLoadAssemblyEvent;
        public static event Action<int> OnUnLoadAssemblyEvent;
        public static event Action<int> OnReLoadAssemblyEvent;
        private static Dictionary<int, AssemblyInfo> AssemblyList = new Dictionary<int, AssemblyInfo>();

主要方法加载某个程序集

        public static void LoadAssembly(int assemblyName, Assembly assembly)
        {
            bool isReload = false;
            if (!AssemblyList.TryGetValue(assemblyName, out AssemblyInfo assemblyInfo))
            {
                assemblyInfo = new AssemblyInfo();
                AssemblyList.Add(assemblyName, assemblyInfo);
            }
            else
            {
                isReload = true;
                assemblyInfo.UnLoad();
                if (OnUnLoadAssemblyEvent != null)
                {
                    OnUnLoadAssemblyEvent(assemblyName);
                }
            }

            assemblyInfo.Load(assembly);

            if (OnLoadAssemblyEvent != null)
            {
                OnLoadAssemblyEvent(assemblyName);
            }

            if (isReload && OnReLoadAssemblyEvent != null)
            {
                OnReLoadAssemblyEvent(assemblyName);
            }
        }

其余遍历程序集方法,根据不同的方式去遍历程序集
在这里插入图片描述
完整AssemblyManager代码

    public static class AssemblyManager
    {
        public static event Action<int> OnLoadAssemblyEvent;
        public static event Action<int> OnUnLoadAssemblyEvent;
        public static event Action<int> OnReLoadAssemblyEvent;
        private static Dictionary<int, AssemblyInfo> AssemblyList = new Dictionary<int, AssemblyInfo>();
        public static void LoadAssembly(int assemblyName, Assembly assembly)
        {
            bool isReload = false;
            if (!AssemblyList.TryGetValue(assemblyName, out AssemblyInfo assemblyInfo))
            {
                assemblyInfo = new AssemblyInfo();
                AssemblyList.Add(assemblyName, assemblyInfo);
            }
            else
            {
                isReload = true;
                assemblyInfo.UnLoad();
                if (OnUnLoadAssemblyEvent != null)
                {
                    OnUnLoadAssemblyEvent(assemblyName);
                }
            }

            assemblyInfo.Load(assembly);

            if (OnLoadAssemblyEvent != null)
            {
                OnLoadAssemblyEvent(assemblyName);
            }

            if (isReload && OnReLoadAssemblyEvent != null)
            {
                OnReLoadAssemblyEvent(assemblyName);
            }
        }
        public static IEnumerable<int> ForeachAssemblyName()
        {
            foreach (int assemblyName in AssemblyList.Keys)
            {
                yield return assemblyName;
            }
        }
        public static IEnumerable<Type> Foreach()
        {
            foreach (AssemblyInfo assemblyInfo in AssemblyList.Values)
            {
                foreach (Type type in assemblyInfo.AssemblyTypeList)
                {
                    yield return type;
                }
            }
        }
        public static IEnumerable<Type> Foreach(int assemblyName)
        {
            if (!AssemblyList.TryGetValue(assemblyName, out AssemblyInfo assemblyInfo))
                yield break;
            foreach (Type type in assemblyInfo.AssemblyTypeList) { yield return type; }
        }
        public static IEnumerable<Type> Foreach(Type findType)
        {
            foreach (AssemblyInfo assemblyInfo in AssemblyList.Values)
            {
                if(!assemblyInfo.AssemblyTypeGroupList.TryGetValue(findType,out List<Type> assemblyLoad))
                    yield break;

                foreach (Type type in assemblyLoad)
                {
                    yield return type;
                }
            }
        }
        public static IEnumerable<Type> Foreach(int assemblyName, Type findType)
        {
            if (!AssemblyList.TryGetValue(assemblyName, out AssemblyInfo assemblyInfo))
                yield break;

            if(!assemblyInfo.AssemblyTypeGroupList.TryGetValue(findType,out List<Type> classList))
                yield break;

            foreach(Type type in classList)
                yield return type;
        }
        public static Assembly GetAssembly(int assemblyName)
        {
            return !AssemblyList.TryGetValue(assemblyName, out AssemblyInfo assemblyInfo) ? null : assemblyInfo.Assembly;
        }
        public static void Dispose()
        {
            foreach (AssemblyInfo assemblyInfo in AssemblyList.Values)
            {
                assemblyInfo.UnLoad();
            }

            AssemblyList.Clear();

            if(OnLoadAssemblyEvent != null)
            {
                foreach (var @delegate in OnLoadAssemblyEvent.GetInvocationList())
                {
                    OnLoadAssemblyEvent -= @delegate as Action<int>;
                }
            }

            if (OnUnLoadAssemblyEvent != null)
            {
                foreach (var @delegate in OnUnLoadAssemblyEvent.GetInvocationList())
                {
                    OnUnLoadAssemblyEvent -= @delegate as Action<int>;
                }
            }

            if (OnReLoadAssemblyEvent != null)
            {
                foreach (var @delegate in OnReLoadAssemblyEvent.GetInvocationList())
                {
                    OnReLoadAssemblyEvent -= @delegate as Action<int>;
                }
            }

            OnLoadAssemblyEvent = null;
            OnUnLoadAssemblyEvent = null;
            OnReLoadAssemblyEvent = null;
        }
    }

3.测试

准备测试的类和接口

    public interface ITest1
    {

    }

    public interface ITest2
    {

    }

    public class TestClass0 
    {

    }

    public class TestClass1 : ITest1
    {

    }

    public class TestClass2 : ITest2
    {

    }

    public class TestClass3 : ITest1, ITest2
    {

    }

进行测试代码

public class Program
    {
        static void Main(string[] args)
        {
            AssemblyManager.OnLoadAssemblyEvent += (assemblyName) =>
            {
                Console.WriteLine($"加载程序集 : {assemblyName}");
            };
            AssemblyManager.OnReLoadAssemblyEvent += (assemblyName) =>
            {
                Console.WriteLine($"重新加载程序集 : {assemblyName}");
            };
            AssemblyManager.OnUnLoadAssemblyEvent += (assemblyName) =>
            {
                Console.WriteLine($"卸载程序集 : {assemblyName}");
            };
            AssemblyManager.LoadAssembly(1, typeof(Program).Assembly);
            foreach (Type type in AssemblyManager.Foreach())
            {
                Console.WriteLine(type.FullName);
            }
            Console.WriteLine("=================================");
            foreach (Type type in AssemblyManager.Foreach(1,typeof(ITest1)))
            {
                Console.WriteLine(type.FullName);
            }
            Console.WriteLine("=================================");
            foreach (Type type in AssemblyManager.Foreach(1, typeof(ITest2)))
            {
                Console.WriteLine(type.FullName);
            }
            Console.ReadKey();
        }
    }

执行结果
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/949928.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java多线程与并发编程

课程地址&#xff1a; https://www.itlaoqi.com/chapter.html?sid98&cid1425 源码文档&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1WMvM3j6qhyjIeAT87kIcxg 提取码&#xff1a;5g56 Java多线程与并发编程 1-并发背后的故事什么是并发 2-你必须知道线程的概念程…

Cadence网表导出常见错误

前言 好不容易绘制出来原理图&#xff0c;结果导出报了很多条错误&#xff0c;由于哥们还是小白&#xff0c;所以很多事情还不懂&#xff0c;有错误的地方希望大佬们能够指出&#xff0c;主要还是以我遇到的为主。 生成网表时候的常见错误 36002-封装名缺失 36003-多part器…

pdf怎么调整大小kb?一分钟学会pdf压缩

PDF是一种常见的文件格式&#xff0c;有时候我们需要将PDF文件的大小进行压缩&#xff0c;以便于传输或存储&#xff0c;那么怎么调整PDF文件的大小呢&#xff1f;接下来就给大家分享几个简单又实用的方法&#xff0c;帮助我们轻松解决PDF文件过大的问题。 方法一&#xff1a;嗨…

【高等数学重点题型篇】——一元函数微分学的应用

本文仅用于个人学习记录&#xff0c;使用的教材为汤家凤老师的《高等数学辅导讲义》。本文无任何盈利或者赚取个人声望的目的&#xff0c;如有侵权&#xff0c;请联系删除&#xff01; 文章目录 一、证明f ( n ) \ ^{(n)} (n)(ξ) 0二、待证结论中只有一个中值ξ&#xff0c;不…

【编译原理】课程一:编译原理入门

目录 1.为什么要学习编译原理 2.什么是编译原理 3.编译与计算机程序设计语言的关系 3.1.程序设计语言的转换方式 3.2.编译的转换过程 3.3.编译器在语言处理系统中的位置 3.4.编译系统的结构 3.4.1.词法分析(扫描) 3.4.2.语法分析(parsing) 3.4.1.1.语法分析的定义 3…

四轴飞行器的电池研究(MatlabSimulink仿真)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Python教程(11)——Python中的字典dict的用法介绍

dict的用法介绍 创建字典访问字典修改字典删除字典字典的相关函数 列表虽然好&#xff0c;但是如果需要快速的数据查找&#xff0c;就必须进行需要遍历&#xff0c;也就是最坏情况需要遍历完一遍才能找到需要的那个数据&#xff0c;时间复杂度是O(n)&#xff0c;显然这个速度是…

Canvas实现3D效果

3D 球 效果图 代码 var canvas document.getElementById("cas"),ctx canvas.getContext("2d"),vpx canvas.width / 2,vpy canvas.height / 2,Radius 150,balls [],angleX Math.PI / 1000,angleY Math.PI / 1000,factor 0.0001 //旋转因子var An…

解决方案 | 法大大电子签为保险行业加个“双保险”

近年来&#xff0c;人们自我保障意识的不断增强&#xff0c;带动了保险行业的蓬勃发展&#xff1b;数字化进程的加快&#xff0c;也让保险签署更加便捷高效。但与此同时&#xff0c;对于保险企业的安全合规化要求也在不断提升&#xff0c;电子签作为企业数字化转型的重要抓手&a…

vue3集成bpmn.js

1 安装依赖 npm install bpmn-js npm install bpmn-js-properties-panel npm install camunda-bpmn-moddle 注意依赖会有冲突&#xff0c;最好按照下列版本来安装&#xff1a; "bpmn-js": "^7.3.1", "bpmn-js-properties-panel": "^0.37.…

量子计算机使模拟化学反应减慢了1000亿倍!

悉尼大学(University of Sydney)的科学家们首次利用量子计算机设计并直接观测了化学反应中的一个关键过程&#xff0c;将其速度减慢了1000亿倍。 “Direct observation of geometric-phase interference in dynamics around a conical intersection” 主要作者Vanessa Olaya Ag…

免费可商用的高清视频素材库分享~

找视频素材绝对不能错过这个6个网站&#xff0c;免费可商用&#xff0c;视频剪辑、自媒体必备&#xff0c;赶紧收藏~ 1、菜鸟图库 https://www.sucai999.com/video.html?vNTYwNDUx 菜鸟图库不仅是一个设计网站&#xff0c;它还有非常丰富的视频和音频素材&#xff0c;视频素材…

[JDK8下的HashMap类应用及源码分析] 数据结构、哈希碰撞、链表变红黑树

系列文章目录 [Java基础] StringBuffer 和 StringBuilder 类应用及源码分析 [Java基础] 数组应用及源码分析 [Java基础] String&#xff0c;分析内存地址&#xff0c;源码 [JDK8环境下的HashMap类应用及源码分析] 第一篇 空构造函数初始化 [JDK8环境下的HashMap类应用及源码分…

Java 复习笔记 - 方法篇

文章目录 一&#xff0c;方法的定义二&#xff0c;最简单的方法定义和调用三&#xff0c;带参数的方法定义和调用四&#xff0c;带返回值方法的定义和调用五&#xff0c;小结六&#xff0c;方法的重载七&#xff0c;方法简单练习1&#xff0c;数组遍历2&#xff0c;数组最大值3…

【深入解读Redis系列】Redis系列(五):切片集群详解

首发博客地址 https://blog.zysicyj.top/ 系列文章地址[1] 如果 Redis 内存很大怎么办&#xff1f; 假设一台 32G 内存的服务器部署了一个 Redis&#xff0c;内存占用了 25G&#xff0c;会发生什么&#xff1f; 此时最明显的表现是 Redis 的响应变慢&#xff0c;甚至非常慢。 这…

Spring框架中如何处理事务管理

文章目录 **1. 声明式事务管理&#xff1a;****定义事务管理器&#xff1a;****配置事务通知&#xff1a;****将事务通知应用到方法&#xff1a;** **2. 编程式事务管理&#xff1a;****通过编程方式启动事务&#xff1a;** **3. 配置事务属性&#xff1a;** &#x1f388;个人…

S32K324芯片学习笔记-实时控制系统-ADC

文章目录 Analog-to-Digital Converter (ADC)用于内部供应监控的ANAMUXBCTU接口硬件触发ADC多路模式通道功能框图特点功能描述时钟转换正常触发注入触发BCTU接口BCTU Trigger modeBCTU Control mode 配置ADC时钟分压器和采样时间设置预采样启用每个通道的预采样 模拟看门狗功能…

阿里云轻量应用服务器Linux-Centos7下MySQL8.0.19的使用

初始环境&#xff1a;阿里云轻量应用服务器已经安装MySQL8.0.19 具体目标&#xff1a;使用MySQL 8.0.19 目录 第一步&#xff1a;初始化第二步&#xff1a;创建一些表第三步&#xff1a;添加一些数据第四步&#xff1a;详情一览第五步&#xff1a;检索数据第六步&#xff1a;排…

前端:js实现提示框(自动消失)

效果&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content&q…

正交实验如何进行方差分析?

一、案例介绍 欲研究温度&#xff08;℃&#xff09;、时间&#xff08;min&#xff09;、催化剂含量&#xff08;%&#xff09;对某物质转化率的影响&#xff0c;当前使用正交试验设计进行试验&#xff0c;试探究3个因素对转化率的影响是否显著&#xff0c;并找到能使转化率达…