AssemblyManager 程序集管理器
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();}}
执行结果
相关文章:

AssemblyManager 程序集管理器
AssemblyManager 程序集管理器 程序执行中使用反射对框架的搭建有着强大的影响,如何管理程序集方便使用反射获取类型操作对象是本文章的重点 1.AssemblyInfo 对于一个程序集这里使用一个AssemblyInfo对象进行管理 Assembly :对应的程序集AssemblyTyp…...

几个nlp的小任务(生成式任务——语言模型(CLM与MLM))
@TOC 本章节需要用到的类库 微调任意Transformers模型(CLM因果语言模型、MLM遮蔽语言模型) CLM MLM 准备数据集 展示几个数据的结构...

单元测试用例mock的使用方法
单元测试用例mock的使用方法 提升代码测试覆盖率的关键策略 为什么单元测试是如此重要? 在软件开发中,单元测试是一个关键的环节,可以确保代码的质量和稳定性。而在进行单元测试时,使用mock对象可以帮助我们更好地测试代码逻辑…...

3D步进式漫游能够在哪些行业应用?
VR技术一直以来都是宣传展示领域中的热门话题,在VR全景技术的不断发展下,3D步进式漫游技术也逐渐覆盖各行各业,特别是在建筑、房产、博物馆、企业等领域应用更加广泛,用户通过这种技术能够获得更加直观、生动、详细的展示体验&…...

2023蓝帽杯初赛ctf部分题目
Web LovePHP 打开网站环境,发现显示出源码 来可以看到php版本是7.4.33 简单分析了下,主要是道反序列化的题其中发现get传入的参数里有_号是非法字符,如果直接传值传入my_secret.flag,会被php处理掉 绕过 _ 的方法 对于__可以…...
vue3+ts封装弹窗,分页封装
定义defaultDialog .vue <script lang"ts" setup> import { ref,toRefs,onUpdated } from vue import { ElMessageBox } from element-plus const props defineProps({//接收参数,父组件传的时候用:msg123的形式msg:String,show:{type:Boolean,defa…...
2023-08-30 数据库-并发控制-冲突可串行化调度-是否可串行化检测-优先图-分析
摘要: 将冲突进行可串行化调度, 是解决冲突是一个基本功能. 对于冲突是否可被串行化调度, 比较有效的就是优先图的方法. 本文对检测冲突可串行化调度的优先图做一些分析. 上下文参考: 2023-08-30 数据库-并发控制-冲突可串行化的调度-思考_财阀悟世的博客-CSDN博客 事务的基…...

人员着装识别算法 yolo
人员着装识别系统通过yolo网络模型识别算法,人员着装识别系统算法通过现场安装的摄像头识别工厂人员及工地人员是否按要求穿戴着装,实时监测人员的着装情况,并进行相关预警。目标检测架构分为两种,一种是two-stage,一种…...

Linux:权限
目录 一、shell运行原理 二、权限 1.权限的概念 2.文件访问权限的相关设置方法 三、常见的权限问题 1.目录权限 2.umsk(权限掩码) 3.粘滞位 一、shell运行原理 1.为什么我们不是直接访问操作系统? ”人“不善于直接使用操作系统如果让人直接访问操作系统&a…...
Unity记录4.3-存储-点击Tilemap保存或读取区块
文章首发见博客:https://mwhls.top/4816.html。 无图/格式错误/后续更新请见首发页。 更多更新请到mwhls.top查看 欢迎留言提问或批评建议,私信不回。 汇总:Unity 记录 摘要:点击tilemap,文件 保存/读取 该地图区块数据…...

【小吉测评】哔哩哔哩接入AI?!效果如何?
文章目录 🎄前言⭐申请方式🏳️🌈注意 🛸简介🍔上手体验🛸进行数学计算🥰可以写代码吗 🎄前言 最近人工智能特别火,chatgpt,Claude2,文心一言等…...

微信开发之一键踢出群聊的技术实现
简要描述: 删除群成员 请求URL: http://域名地址/deleteChatRoomMember 请求方式: POST 请求头Headers: Content-Type:application/jsonAuthorization:login接口返回 参数: 参数名必选…...

基于Spring Boot 的 Ext JS 应用框架之coworkee
Ext JS 官方提供了一个人员管理的完整应用框架 - coworkee。该框架的显示如下: 该框架的布局特点如下: 布局方式: 左右布局, 左侧导航栏默认收合特点:左侧导航区占用空间小, 工作区较大, 适合没有二级导航栏,工作区需要显示的内容较多的系统。如果导航栏是横向底部,就…...
HOT100打卡—day10—【DP+多维DP】—最新8.29(剩6题)
DP 1 70. 爬楼梯 70. 爬楼梯 一次做,AC代码: 疑问:怎么判断用搜索还是dp?这题,我没有受过dp训练所以第一反应是用dfs搜索,找到所有符合要求的叶子。 class Solution { public:int dp[50]; // step1&a…...

【不会用这个工具,你的Linux服务器就是个摆设!】
01 Tcpdump Tcpdump 是一个强大的网络监控工具,它允许用户有效地过滤网络上的数据包和流量。 这可以获得有关 TCP/IP 和网络上传输的数据包的详细信息。 当你遇到网络协议问题一筹莫展的时候,这时候往往可以通过tcpdump来看网络的通讯过程中发生了什么…...
09 生产者分区机制
kafka如何保证消息的有序 可以通过key-ording策略解决。kafka可以为每条消息定义消息键,也称为key,通常是带有业务属性的比如用户id之类的。有相同消息键的消息会被发到同一个分区。下面实现了key-ordering策略,对key的hashcode进行取模来决…...

亚马逊鲲鹏系统是怎么操作测评的
亚马逊鲲鹏系统可以注册亚马逊买家号、养号、下单留评等,是一款功能比较齐全的测评软件,具体操作如下: 首先我们需要先准备好买家账号,账号可以直接去购买已经注册好了的账号,也可以准备好账号所需要的一些邮箱、ip、…...

电脑上的视频如何导入苹果手机?
AirDroid支持Windows、macOS、android、iOS相互传输文件、视频、图片等。 想要从电脑传输文件到iPhone也很简单,在电脑和iPhone都安装AirDroid,连接同一网络,然后登录同一个帐号就可以了。可绑定的iPhone数量不限,只要都登录同一…...

tsmc standard cell命名规则
我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 CKMUX2代表二输入clock mux,D2代表驱动强度X2,6T代表row高为6track,16P96C代表gate length和poly pitch,LVT就是low voltage thr…...

基于ssm医院在线挂号预约系统源码和论文
基于ssm医院在线挂号预约系统源码和论文072 开发工具:idea 数据库mysql5.7 数据库链接工具:navcat,小海豚等 技术:ssm 课题研究的目的及意义: 专家号难求,是医院现场挂号存在的主要问题之一,每一名专…...

Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...

C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...

LabVIEW双光子成像系统技术
双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制,展现出显著的技术优势: 深层组织穿透能力:适用于活体组织深度成像 高分辨率观测性能:满足微观结构的精细研究需求 低光毒性特点:减少对样本的损伤…...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅
目录 前言 操作系统与驱动程序 是什么,为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中,我们在使用电子设备时,我们所输入执行的每一条指令最终大多都会作用到硬件上,比如下载一款软件最终会下载到硬盘上&am…...