原文:仅反射加载(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

代码解读是这样的:

  1. 我们从拿到的所有的 Attribute 元数据中找到第一个名称与 AssemblyFileVersionAttribute 相同的数据;
  2. 从数据的构造函数参数中找到传入的参数值,而这个值就是我们定义 AssemblyFileVersionAttribute 时传入的参数的实际值。

因为我们知道 AssemblyFileVersionAttribute 的构造函数只有一个,所以我们确信可以从第一个参数中拿到我们想要的值。

顺便一提,我们使用 AssemblyFileVersionAttribute 而不是使用 AssemblyVersionAttribute 是因为使用 .NET Core 新格式(基于 Microsoft.NET.Sdk)编译出来的程序集默认是不带 AssemblyVersionAttribute 的。详见:语义版本号(Semantic Versioning) - walterlv


参考资料


我的博客会首发于 https://blog.walterlv.com/,而 CSDN 会从其中精选发布,但是一旦发布了就很少更新。

如果在博客看到有任何不懂的内容,欢迎交流。我搭建了 dotnet 职业技术学院 欢迎大家加入。

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名吕毅(包含链接:https://walterlv.blog.csdn.net/),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

发布了382 篇原创文章 · 获赞 232 · 访问量 47万+

仅反射加载(ReflectionOnlyLoadFrom)的 .NET 程序集,如何反射获取它的 Attribute 元数据呢?的更多相关文章

  1. Unity热更新之C#反射加载程序集

    用C#反射加载程序集的方式可以动态的从assetBundle资源包或其他资源包里加载脚本到工程中,即便是原工程中不存在的脚本. 我这里就用加载本地assetBundle的方式来进行讲解了,加载网络上的 ...

  2. Quartz.net 2.x 学习笔记03-使用反射加载定时任务

    将定时任务信息存储在XML文件中,使用反射加载定时任务 首先新建一个MVC的空站点,使用NuGet添加对Quartz.net和Common.Logging.Log4Net1213的引用,同时使用NuG ...

  3. c# 动态加载和卸载DLL程序集

    原文:c# 动态加载和卸载DLL程序集 在 C++中加载和卸载DLL是一件很容易的事,LoadLibrary和FreeLibrary让你能够轻易的在程序中加载DLL,然后在任何地方卸载.在 C#中我们 ...

  4. WPF 反射加载Geometry几何图形数据图标

    相信大家在阅读WPF相关GitHub开源项目源码时都会看见一串串这种数据 这种Geometry数据就是几何图形数据 为什么要用Geometry数据做图标? 有一种做法是使用ttf字体文件代替,不过使用 ...

  5. C#使用反射加载多个程序集

    当开发插件的时候需要用到反射,在客户端动态加载遍历程序集,并调用每个程序集的方法. 创建一个控制台应用程序,首先设计一个接口: public interface ISay { void SaySth( ...

  6. 对tomcat中使用反射加载类的理解

    public void init() throws Exception { initClassLoaders(); //加载一下jar包和类 Thread.currentThread().setCon ...

  7. 反射01 Class类的使用、动态加载类、类类型说明、获取类的信息

    0 Java反射机制 反射(Reflection)是 Java 的高级特性之一,是框架实现的基础. 0.1 定义 Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对 ...

  8. .Net6新版本的AssemblyLoadContext 加载程序集和卸载程序集

    准备俩个项目 第一个是控制台 第二个项目是类库 类库项目中只有一个示例class 将类库的代码生成dll 并且设置属性为复制到输出目录 using System.Runtime.Loader; var ...

  9. iOS 利用webView加载html代码,在代理中获取html页面的链接时出现的问题

    getDetailWebview.loadHTMLString(webViewData as String, baseURL:NSURL(string: "\(ProBaseWeb)&quo ...

随机推荐

  1. 记录一次利用 python 进行日志模块开发过程

    只记录大体思路和我认为其中需要记录的地方. 正则匹配 正则匹配的模式很难记忆,即使记住了,也很难写出无错误的匹配模式.但是,借助网上一些提供实时对比的网站,如 regexr.com. 代码示意: im ...

  2. SpringBoot之AOP使用

    说到SpringBoot,难免会想到Spring.对于Spring,我曾用其开发过很多大大小小的项目.当使用SpringBoot之后,给人最直观的感受,用古人一句话:”大道至简”. SpringBoo ...

  3. 探索ENCODE数据库 | Encyclopedia of DNA Elements

    ENCODE: Encyclopedia of DNA Elements 目标:按不同组织,收集人类(还有小鼠.worm.fly)基因组里面的所有功能元件 The primary goal of th ...

  4. 【python基础学习】基础重点难点知识汇总

    python中decorator装饰器 语法示例: @decorator 什么是装饰器: 问题: 定义一个函数后 在运行时动态增加功能 又不想改动函数本身的代码 示例: # 希望对下列函数调用增加lo ...

  5. SpatiaLite, load spatial extension first

  6. spring-boot 知识集锦

    1.spring-boot项目在外部tomcat环境下部署 https://blog.csdn.net/james_wade63/article/details/51009423 https://bl ...

  7. 关于在php中变量少写了一个$和页面不断转圈的问题排查和vim的自动补全方式

    php中的所有变量都是页面级的, 即任何一个页面, 最多 都只能在一个文件 : 当前页面内使用, 不存在跨 文件/ 跨页面的 作用域的变量! 因此, 即使是 $GLOBALS 这个变量, 虽然叫全局 ...

  8. ios 打包相关的那些报错

    这张图片是因为打包bitcode的时候出现了失败,重新打包即可 这个是因为电脑容量不足导致的无法启动模拟器,这个经常发生在128g的电脑并且同时开启多个模拟器的情况下 打完包后,苹果会给你发邮件告诉你 ...

  9. 028_Mac急救箱快捷键

    一. (1) 1.shift + control + option + 电源键 +长按10秒 "重置系统管理器" 2.option + command + P + R + 按1下电 ...

  10. aardio类的例子

    论坛里面相关资料太少,这里贴一下 库需要在工程的lib目录下,在ide里面就是用户库目录,比如 my_lib namespace my_lib{ import console class MyLibC ...