仅反射加载(ReflectionOnlyLoadFrom)的 .NET 程序集,如何反射获取它的 Attribute 元数据呢?
原文:仅反射加载(ReflectionOnlyLoadFrom)的 .NET 程序集,如何反射获取它的 Attribute 元数据呢?
平时我们获取一个程序集或者类型的 Attribute
是非常轻松的,只需要通过 GetCustomAttribute
方法就能拿到实例然后获取其中的值。但是,有时我们仅为反射加载一些程序集的时候,获取这些元数据就不那么简单了,因为我们没有加载目标程序集中的类型。
本文介绍如何为仅反射加载的程序集读取 Attribute 元数据信息。
仅反射加载一个程序集
使用 ReflectionOnlyLoadFrom
可以仅以反射的方式加载一个程序集。
var extensionFilePath = @"C:\Users\walterlv\Desktop\Walterlv.Extension.dll";
var assembly = Assembly.ReflectionOnlyLoadFrom(extensionFilePath);
- 1
- 2
获取程序集的 Attribute(例如获取程序集版本号)
Assembly.GetCustomAttributesData()
得到的是一个 CustomAttributeData
的列表,而这个列表中的每一项都与普通反射中拿到的特性集合不同,这里拿到的只是特性的信息(以下循环中的 data
变量)。
CustomAttributeData
中有 AttributeType
属性,虽然此属性是 Type
类型的,但是实际上它只会是 RuntimeType
类型,而不会是真实的 Attribute
的类型(因为不能保证宿主程序域中已经加载了那个类型)。
var customAttributesData = assembly.GetCustomAttributesData();
foreach (CustomAttributeData data in customAttributesData)
{
// 这里可以针对每一个拿到的慝的信息进行操作。
}
- 1
- 2
- 3
- 4
- 5
比如我们要获取这个程序集的版本号,正常我们写 assembly.GetCustomAttribute<AssemblyFileVersionAttribute>().Version
,但是这里我们无法生成 AssemblyFileVersionAttribute
的实例,我们只能这么写:
var versionString = assembly.GetCustomAttributesData()
.FirstOrDefault(x => x.AttributeType.FullName == typeof(AssemblyFileVersionAttribute).FullName)
?.ConstructorArguments[0].Value as string ?? "0.0";
var version = new Version(versionString);
- 1
- 2
- 3
- 4
代码解读是这样的:
- 我们从拿到的所有的
Attribute
元数据中找到第一个名称与AssemblyFileVersionAttribute
相同的数据; - 从数据的构造函数参数中找到传入的参数值,而这个值就是我们定义
AssemblyFileVersionAttribute
时传入的参数的实际值。
因为我们知道 AssemblyFileVersionAttribute
的构造函数只有一个,所以我们确信可以从第一个参数中拿到我们想要的值。
顺便一提,我们使用 AssemblyFileVersionAttribute
而不是使用 AssemblyVersionAttribute
是因为使用 .NET Core 新格式(基于 Microsoft.NET.Sdk)编译出来的程序集默认是不带 AssemblyVersionAttribute
的。详见:语义版本号(Semantic Versioning) - walterlv。
参考资料
- CustomAttributeData Class (System.Reflection) - Microsoft Docs
- c# - How to get custom attributes from an assembly that is not (really) loaded - Stack Overflow
- c# - Get custom attribute data from assembly file and unlock it afterwise - Stack Overflow
我的博客会首发于 https://blog.walterlv.com/,而 CSDN 会从其中精选发布,但是一旦发布了就很少更新。
如果在博客看到有任何不懂的内容,欢迎交流。我搭建了 dotnet 职业技术学院 欢迎大家加入。
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名吕毅(包含链接:https://walterlv.blog.csdn.net/),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。
仅反射加载(ReflectionOnlyLoadFrom)的 .NET 程序集,如何反射获取它的 Attribute 元数据呢?的更多相关文章
- Unity热更新之C#反射加载程序集
用C#反射加载程序集的方式可以动态的从assetBundle资源包或其他资源包里加载脚本到工程中,即便是原工程中不存在的脚本. 我这里就用加载本地assetBundle的方式来进行讲解了,加载网络上的 ...
- Quartz.net 2.x 学习笔记03-使用反射加载定时任务
将定时任务信息存储在XML文件中,使用反射加载定时任务 首先新建一个MVC的空站点,使用NuGet添加对Quartz.net和Common.Logging.Log4Net1213的引用,同时使用NuG ...
- c# 动态加载和卸载DLL程序集
原文:c# 动态加载和卸载DLL程序集 在 C++中加载和卸载DLL是一件很容易的事,LoadLibrary和FreeLibrary让你能够轻易的在程序中加载DLL,然后在任何地方卸载.在 C#中我们 ...
- WPF 反射加载Geometry几何图形数据图标
相信大家在阅读WPF相关GitHub开源项目源码时都会看见一串串这种数据 这种Geometry数据就是几何图形数据 为什么要用Geometry数据做图标? 有一种做法是使用ttf字体文件代替,不过使用 ...
- C#使用反射加载多个程序集
当开发插件的时候需要用到反射,在客户端动态加载遍历程序集,并调用每个程序集的方法. 创建一个控制台应用程序,首先设计一个接口: public interface ISay { void SaySth( ...
- 对tomcat中使用反射加载类的理解
public void init() throws Exception { initClassLoaders(); //加载一下jar包和类 Thread.currentThread().setCon ...
- 反射01 Class类的使用、动态加载类、类类型说明、获取类的信息
0 Java反射机制 反射(Reflection)是 Java 的高级特性之一,是框架实现的基础. 0.1 定义 Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对 ...
- .Net6新版本的AssemblyLoadContext 加载程序集和卸载程序集
准备俩个项目 第一个是控制台 第二个项目是类库 类库项目中只有一个示例class 将类库的代码生成dll 并且设置属性为复制到输出目录 using System.Runtime.Loader; var ...
- iOS 利用webView加载html代码,在代理中获取html页面的链接时出现的问题
getDetailWebview.loadHTMLString(webViewData as String, baseURL:NSURL(string: "\(ProBaseWeb)&quo ...
随机推荐
- navicat提示无法连接解决办法
1.错误如下图: 2.这个是由于mysql中user表中未设置允许该ip访问导致,解决办法: 1)查下user表:select user,host from user; 这张表就是mysql.user ...
- 【cf比赛记录】Codeforces Round #600 (Div. 2)
Codeforces Round #600 (Div. 2) ---- 比赛传送门 昨晚成绩还好,AC A,B题,还能上分(到底有多菜) 补了C.D题,因为昨晚对C.D题已经有想法了,所以补起题来也快 ...
- 利用sftp迁移pve虚拟机
首先在A主机进行虚拟机备份vzdump <vmid>在B主机利用sftp复制备份到A主机cd /var/lib/vz/dump/sftp root@192.168.25.140 回答yes ...
- jmeter-可视化的非GUI模式
概述 我们在使用JMeter执行性能测试的过程中,会遇到很多不方便的地方 GUI模式 执行脚本很方便,看结果也很方便,但是GUI模式消耗资源,对测试结果的准确性影响很大 非GUI模式 消耗资源很少,但 ...
- idea打包web项目
打包完成的文件在如下路径
- hdu2094产生冠军[STL set]
目录 题目地址 题干 代码和解释 参考 题目地址 hdu2094 题干 代码和解释 题意可以这样理解:一个人只要没输过就可以是冠军,如果没输过的人恰为一位,那就认他为冠军,若少于或多于一位,则判定没有 ...
- [Beta阶段]测试报告
[Beta阶段]测试报告 博客目录 测试方法及过程 在正式发布前,为检验后端各接口功能的正确性,后端服务器对压力的耐受程度,以及前端各页面.功能的运行情况,我们对我们的服务器及小程序进行了多种测试.除 ...
- CandyCrush 糖果传奇源码+素材+教程
在这里你将深入学习C#语言和Unity开发游戏的技术.在游戏项目开发中深入学习并掌握Unity开发中的刚体,模型等等 共14讲,TS格式,大小395MB 共14讲,TS格式,大小395MB 扫码时备注 ...
- SpringMVC(十四):SpringMVC 与表单提交(post/put/delete的用法);form属性设置encrypt='mutilpart/form-data'时,如何正确配置web.xml才能以put方式提交表单
SpringMVC 与表单提交(post/put/delete的用法) 为了迎合Restful风格,提供的接口可能会包含:put.delete提交方式.在springmvc中实现表单以put.dele ...
- 微信小程序图片宽度100%,高度自适应
实现图片自适应,按照一般情况只需设置: img { width: 100%; height: auto; } 但是微信小程序里是特例,需要image标签上设置属性mode=widthFix,就是hei ...