【C#反射】Assembly
Assembly属性的应用
//获取当前执行代码的程序集
Assembly assem = Assembly.GetExecutingAssembly();
Console.WriteLine($"程序集全名:{assem.FullName}" );
Console.WriteLine($"程序集的版本:{assem.GetName().Version}" );
Console.WriteLine($"程序集位置:{assem.Location}" );
Console.WriteLine($"程序集入口:{assem.EntryPoint}");
Console.WriteLine($"获取用于加载程序集的主机上下文:{assem.HostContext}");
Console.WriteLine($"是否保留在可回收的 AssemblyLoadContext 中:{assem.IsCollectible}");
Console.WriteLine($"CLR 版本的文件夹名:{assem.ImageRuntimeVersion}");
Console.WriteLine($"当前程序集是否在当前进程中动态生成的:{assem.IsDynamic}");
Console.WriteLine($"当前程序集是否以完全信任方式加载:{assem.IsFullyTrusted}");
Console.WriteLine($"当前程序集清单的模块:{assem.ManifestModule}");
Console.WriteLine($"获取包含此程序集中模块的集合:{assem.Modules}");
Console.WriteLine($"程序集被加载到只反射上下文而不是执行上下文中:{assem.ReflectionOnly}");
Console.WriteLine($"CLR 对此程序集强制执行的安全规则集:{assem.SecurityRuleSet}");
Type[] types = assem.GetTypes();
Console.WriteLine("程序集下包含的类型:");
foreach (var item in types)
{ Console.WriteLine($"类:{item.Name}");
}
//输出结果:
//程序集全名:ConsoleApp3, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
//程序集的版本:1.0.0.0
//程序集位置:C:\Users\HP\source\repos\ConsoleApp3\bin\Debug\net5.0\ConsoleApp3.dll
//程序集入口:Void Main(System.String[])
//获取用于加载程序集的主机上下文:0
//是否保留在可回收的 AssemblyLoadContext 中:False
//CLR 版本的文件夹名:v4.0.30319
//当前程序集是否在当前进程中动态生成的:False
//当前程序集是否以完全信任方式加载:True
//当前程序集清单的模块:ConsoleApp3.dll
//获取包含此程序集中模块的集合:System.Reflection.RuntimeModule[]
//程序集被加载到只反射上下文而不是执行上下文中:False
//CLR 对此程序集强制执行的安全规则集:None
//程序集下包含的类型:
//类:Program
//类:Person
//类:Employee
Assembly方法的应用
使用System.Reflection.Assembly类动态加载程序集(.dll)
Assembly类可以获得程序集的信息,也可以动态的加载程序集,以及在程序集中查找类型信息,并创建该类型的实例。 使用Assembly类可以降低程序集之间的耦合,有利于软件结构的合理化。
Assembly.Load()方法,Assembly.LoadFrom()方法,Assembly.LoadFile()方法的区别!
LoadFrom()、LoadFile()这俩方法会锁住文件,导致程序运行期间无法对load过的程序集文件进行更名/删除/覆盖等等操作,考虑用Assembly.Load()文件字节组替代:Load()其他方法加载文件也会锁住文件。
以下程序集不能共享 JIT 编译代码:使用Assembly 类的 LoadFrom 方法加载到“加载源”上下文中的程序集,或者使用 Load 方法的重载(指定字节数组 Load(byte[] rawAssembly、Load(byte[] rawAssembly, byte[]? rawSymbolStore))从图像加载的程序集。也就是说用这些方法加载的程序集只能给当期程序集使用,不能共享给其他程序集使用 详细请看:应用程序域和程序集
(1)Assembly.Load() 加载程序集
在使用这个函数之前要添加对程序集的引用,以.net core 5.0为例。
点击确定。添加成功后,查看项目的配置文件ConsoleApp4.csproj
此时会多出一条配置信息 如下图所示,很多时候load()无法加载函数都是因为配置文件未添加引用程序集信息。也可以手动添加该信息 引用程序集。
以上配置完成后就可以在.net core中正常使用Load函数加载程序集了。.net framework框架下也要添加程序集的引用
// Assembly.Load 函数的使用
Byte[] syd = System.IO.File.ReadAllBytes("Education.dll");//在指定的路径下获取程序集,不需要添加引用,默认当前当前程序集的目录下获取
Assembly assemblyLoadByte = Assembly.Load(syd); //必须把程序集添加为引用 才能正常使用该函数功能
Assembly assemblyLoadFullname= Assembly.Load("Education, Version = 1.1.0.0, Culture = neutral, PublicKeyToken = be45ec9bf8b890a7");
Assembly assemblyLoadPartialname = Assembly.Load("Education");
(2)Assembly.LoadFrom()加载 Assembly对象
LoadFrom()方法可以从指定文件中加载程序集,通过查找程序集的AssemblyRef元数据表,得知所有引用和需要的程序集,然后在内部调用Load()方法进行加载。
加载进的程序集实例存储在 AssemblyLoadContext.Default这个context中,和程序的依赖项存储在一起。如果希望存储在单独的context中 ,查看AssemblyLoadContext详细用法
例如:
Assembly.LoadFrom(@"C:\ABC\Test.dll");
Assembly ass = Assembly.LoadFrom("ClassLibrary831.dll");//文件在当前程序目录下
这个方法从指定的路径来加载程序集,实际上这个方法被调用的时候,CLR会打开这个文件,获取其中的程序集版本,语言文化,公钥标记等信息,把他们传递给 Load方法,接着,Load方法采用上面的策略来查找程序集。如果找到了程序集,会和LoadFrom方法中指定的路径做比较,如果路径相同,该程序集会被认为是应用程序的一部分,如果路径不同或Load方法没有找到程序集,那该程序集只是被作为一个“数据文件”来加载,不会被认为是应用程序的一部分。 这就是在第1点中提到的Load方法比LoadFrom方法的执行效率高的原因。另外,由于可能把程序集作为“数据文件”来加载,所以使用 LoadFrom从不同路径加载相同程序集的时候会导致重复加载。当然这个方法会加载此程序集引用的其他程序集。
(3)Assembly.LoadFile()加载 Assembly对象
这个方法是从指定的文件来加载程序集,和上面方法的不同之处是这个方法不会加载此程序集引用的其他程序集!
结论:一般大家应该优先选择Load方法来加载程序集,如果遇到需要使用LoadFrom方法的时候,最好改变设计而用Load方法来代替!
(4) ,LoadWithParitalName方法
对于,LoadWithParitalName方法,推荐大家最好不要使用它,因为程序无法确定最终要去加载哪个程序集的版本,所以我们这里只是简单的介绍一下它的工作原理:你可以传递一个程序集标识给它,包括程序集名称,至于其他信息是可选的(区域信息,公有密钥等),该方法执行时,会首先检查应用程序中配置文件的qualifyAssembly节点,如果存在,则把该部分名称的程序集替换成完全的程序集标识,如果不存在,则使用程序集名称先到应用程序根目录下查找,然后是私有目录,没有找到的话,就到程序集全局缓存中查找。简单过程如下:
应用程序根目录 -> 应用程序私有目录 -> 程序集全局缓存.
Assembly.LoadFile 与 Assembly.LoadFrom的区别
1、Assembly.LoadFile只载入相应的dll文件,比如Assembly.LoadFile("abc.dll"),则载入abc.dll,假如abc.dll中引用了def.dll的话,def.dll并不会被载入。
Assembly.LoadFrom则不一样,它会载入dll文件及其引用的其他dll,比如上面的例子,def.dll也会被载入。
2、用Assembly.LoadFrom载入一个Assembly时,会先检查前面是否已经载入过相同名字的Assembly,比如abc.dll有两个版本(版本1在目录1下,版本2放在目录2下),程序一开始时载入了版本1,当使用Assembly.LoadFrom("2\\abc.dll")载入版本2时,不能载入,而是返回版本1。Assembly.LoadFile的话则不会做这样的检查,比如上面的例子换成Assembly.LoadFile的话,则能正确载入版本2。
LoadFile:加载指定路径上的程序集文件的内容。LoadFrom: 根据程序集的文件名加载程序集文件的内容。
Assembly.CreateInstance()创建实例
assembly.CreateInstance已经获知程序集所有元数据,所以只要指定命名空间.类名 就可以生成实例了。Activator.CreateInstance未获得元数据,所以需要typeof函数先获取元数据类型信息,然后才能实例化。点击查看Activator.CreateInstance实例化
// Assembly.Load 函数的使用
Byte[] syd = System.IO.File.ReadAllBytes("Education.dll");//在指定的路径下获取程序集,不需要添加引用,默认当前当前程序集的目录下获取
Assembly assemblyLoadByte = Assembly.Load(syd); //必须把程序集添加为引用 采用正常使用该函数功能
Assembly assemblyLoadFullname= Assembly.Load("Education, Version = 1.1.0.0, Culture = neutral, PublicKeyToken = be45ec9bf8b890a7");
Assembly assemblyLoadPartialname = Assembly.Load("Education"); //Assembly.CreateInstance根据空间名.类型名创建实例,已经获得程序集所有的元数据,所以可以用这种放射创建
object person = assemblyLoadByte.CreateInstance("People.Person");
object stu = assemblyLoadByte.CreateInstance("Education.Student");
Type studentType = assemblyLoadByte.GetType("Education.Student");//名空间+类名 才能挣钱获取类型
Assembly.GetExecutingAssembly();
Assembly assem = Assembly.GetExecutingAssembly(); //获取当前执行代码的程序集
Assembly其他应用
通过Assembly获取程序集中类
Type t = ass.GetType("ClassLibrary831.NewClass"); //参数必须是类的全名
通过Assembly获取程序集中所有的类
Type[] t = ass.GetTypes(); //通过程序集的名称反射
Assembly ass = Assembly.Load("ClassLibrary831");
Type t = ass.GetType("ClassLibrary831.NewClass");
object o = Activator.CreateInstance(t, "grayworm", "http://hi.baidu.com/grayworm");
MethodInfo mi = t.GetMethod("show");
mi.Invoke(o, null); //通过DLL文件全名反射其中的所有类型
Assembly assembly = Assembly.LoadFrom("xxx.dll的路径");
Type[] aa = a.GetTypes();
foreach(Type t in aa)
{
if(t.FullName == "a.b.c")
{
object o = Activator.CreateInstance(t);
}
}
【C#反射】Assembly的更多相关文章
- 关于反射Assembly.Load("程序集").CreateInstance("命名空间.类")
关于反射Assembly.Load("程序集").CreateInstance("命名空间.类") 而不管在哪一层写这段代码其中的("程序集" ...
- [转]C#反射-Assembly.Load、LoadFrom与LoadFile进阶
关于.NET中的反射,常用的有三个方法: Assembly.Load()Assembly.LoadFrom()Assembly.LoadFile() 下面说说这三个方法的区别和一些细节问题 1. As ...
- C#反射Assembly 详细说明
1.对C#反射机制的理解2.概念理解后,必须找到方法去完成,给出管理的主要语法3.最终给出实用的例子,反射出来dll中的方法 反射是一个程序集发现及运行的过程,通过反射可以得到*.exe或*.dll等 ...
- C#中的反射 Assembly.Load() Assembly.LoadFrom()
一些关于C#反射的知识,估计也就最多达到使用API的程度,至于要深入了解,以现在的水平估计很难做到,所以下面此篇文章,以作为一个阶段的总结. 对于反射的总结,我想从以下几个方面展开,首先是反射程序集, ...
- C#反射Assembly 具体说明
1.对C#反射机制的理解 2.概念理解后,必须找到方法去完毕,给出管理的主要语法 3.终于给出有用的样例,反射出来dll中的方法 反射是一个程序集发现及执行的过程,通过反射能够得到*.exe或*.dl ...
- C#反射-Assembly.Load、LoadFrom与LoadFile
反射Demo: public class Person { public int Age; public void SayHello() { Console.WriteLine("Hello ...
- C#反射Assembly 详细说明,有项目例子
1.对C#反射机制的理解2.概念理解后,必须找到方法去完成,给出管理的主要语法3.最终给出实用的例子,反射出来dll中的方法 反射是一个程序集发现及运行的过程,通过反射可以得到*.exe或*.dll等 ...
- C#反射Assembly 详细说明(转)
1.对C#反射机制的理解2.概念理解后,必须找到方法去完成,给出管理的主要语法3.最终给出实用的例子,反射出来dll中的方法 反射是一个程序集发现及运行的过程,通过反射可以得到*.exe或*.dll等 ...
- c#利用反射Assembly 对类和成员属性进行操作
protected static void test() { //获取程序集 Assembly assembly = System.Reflection.Assembly.GetExecutingAs ...
随机推荐
- 虚拟化架构与Centos7系统部署
1.什么是虚拟化(Virtualization) 虚拟化,是指通过虚拟化技术将一台计算机虚拟为多台逻辑计算机.在一台计算机上同时运行多个逻辑计算机,每个逻辑计算机可运行不同的操作系统,并且应用程序都可 ...
- Ajax_axios发送ajax请求
Ajax_axios发送ajax请求 这篇笔记主要讲一下axios基本的发送ajax请求的方法 axios在当前的前端行业里面是用的比较热门的一个 下面给大家分享一下它axios的一个基本用法 这段代 ...
- 微服务架构 | 2.2 Alibaba Nacos 的统一配置管理
目录 前言 1. Nacos 配置中心基础知识 1.1 Nacos 在配置中心中的功能 1.2 Nacos 配置管理 Data ID 的构成 1.3 Nacos 配置的回滚机制 1.4 Nacos 配 ...
- presence_of_element_located对比visibility_of_element_located
presence_of_element_located和visibility_of_element_located都是selenium里判断元素展示的方法,相信做ui自动化的小伙伴一定被这俩困扰过,本 ...
- Go 结构体方法
#### Go 结构体方法本来今天有些事情忙的不准备更新内容了,后来提前完成了, 所以还是要更新了; 毕竟坚持本就是一件不容易的事情!加油,相信不管是大家还是我,都有一些事情想要做,那就坚持吧,剩下的 ...
- linux安装第三方软件 python3
一:linux安装python3 安装第三方软件的目录 进入目录 /usr/local 下载rpm安装包 安装pyton yum安装python : yum install python3 查看pyt ...
- 学习JAVAWEB第十三天
会话技术 1. 会话:一次会话中包含多次请求和响应. * 一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止 2. 功能:在一次会话的范围内的多次请求间,共享数据 3. 方式: ...
- Codeforces Round #738 (Div. 2)
Codeforces Round #738 (Div. 2) 跳转链接 A. Mocha and Math 题目大意 有一个长度为\(n\)的数组 可以进行无数次下面的操作,问操作后数组中的最大值的最 ...
- 求一个number数组中的最大值和最小值的差
<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content ...
- TableView 常用技巧与功能详解
分割线顶格iOS8 UITableview分割线顶格的做法 //iOS8 Cell分割线顶格 if ([_tableView respondsToSelector:@selector(setSepar ...