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的更多相关文章

  1. 关于反射Assembly.Load("程序集").CreateInstance("命名空间.类")

    关于反射Assembly.Load("程序集").CreateInstance("命名空间.类") 而不管在哪一层写这段代码其中的("程序集" ...

  2. [转]C#反射-Assembly.Load、LoadFrom与LoadFile进阶

    关于.NET中的反射,常用的有三个方法: Assembly.Load()Assembly.LoadFrom()Assembly.LoadFile() 下面说说这三个方法的区别和一些细节问题 1. As ...

  3. C#反射Assembly 详细说明

    1.对C#反射机制的理解2.概念理解后,必须找到方法去完成,给出管理的主要语法3.最终给出实用的例子,反射出来dll中的方法 反射是一个程序集发现及运行的过程,通过反射可以得到*.exe或*.dll等 ...

  4. C#中的反射 Assembly.Load() Assembly.LoadFrom()

    一些关于C#反射的知识,估计也就最多达到使用API的程度,至于要深入了解,以现在的水平估计很难做到,所以下面此篇文章,以作为一个阶段的总结. 对于反射的总结,我想从以下几个方面展开,首先是反射程序集, ...

  5. C#反射Assembly 具体说明

    1.对C#反射机制的理解 2.概念理解后,必须找到方法去完毕,给出管理的主要语法 3.终于给出有用的样例,反射出来dll中的方法 反射是一个程序集发现及执行的过程,通过反射能够得到*.exe或*.dl ...

  6. C#反射-Assembly.Load、LoadFrom与LoadFile

    反射Demo: public class Person { public int Age; public void SayHello() { Console.WriteLine("Hello ...

  7. C#反射Assembly 详细说明,有项目例子

    1.对C#反射机制的理解2.概念理解后,必须找到方法去完成,给出管理的主要语法3.最终给出实用的例子,反射出来dll中的方法 反射是一个程序集发现及运行的过程,通过反射可以得到*.exe或*.dll等 ...

  8. C#反射Assembly 详细说明(转)

    1.对C#反射机制的理解2.概念理解后,必须找到方法去完成,给出管理的主要语法3.最终给出实用的例子,反射出来dll中的方法 反射是一个程序集发现及运行的过程,通过反射可以得到*.exe或*.dll等 ...

  9. c#利用反射Assembly 对类和成员属性进行操作

    protected static void test() { //获取程序集 Assembly assembly = System.Reflection.Assembly.GetExecutingAs ...

随机推荐

  1. 不难懂——th: 的常用标签

    关键字>       功能介绍    >      案例 th:id 替换id <input th:id="'xxx' + ${collect.id}"/> ...

  2. 『无为则无心』Python函数 — 38、Python中的异常

    目录 1.异常概念 2.了解异常 3.异常的写法 (1)语法 (2)快速体验 (3)捕获指定异常 (4)异常中的else (5)异常中的finally (6)总结 1.异常概念 定义:程序在运行过程当 ...

  3. Linux配置 ftp 和 ftp简单介绍

    一.ftp概念? /* ftp是一个协议和http协议都是叫协议 tcp和udp也是协议 ftp是文件(以流的形式进行传输)传输协议(针对于文件进行上传和下载) */ 1.如果ftp服务器有多台,服务 ...

  4. 「IOI2009」旅行商

    题目传送门 首先,看到这道题感觉就像dp(然鹅没什么用). 一个美好的设想 假如没有两个展销会在同一天开展:前途光明 暴力dp,复杂度o(\(n^2\)). 没有同一天的展销会 暴力dp慢,是因为本质 ...

  5. Java-打印杨辉三角

    记录下哈 import java.util.Scanner; public class YangHuiTriangle { public static void main(String[] args) ...

  6. linux 进程信号

    转载请注明来源:https://www.cnblogs.com/hookjc/ signal 函数的使用方法简单,但并不属于 POSIX 标准,在各类 UNIX 平台上的实现不尽相同,因此其用途受 到 ...

  7. play的action链(一个action跳转到另一个action,类似于重定向)

    在play中没有Servlet API forward 的等价物.每一个HTTP request只能调用一个action.如果我们需要调用另一个,必须通过重定向,让浏览器访问另一个URL来访问它.这样 ...

  8. Static块和类加载顺序

    原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11451040.html  版本:Java8 直接上代码: public class Stati ...

  9. Shell之awk

    Shell之awk 目录 Shell之awk 一.awk概述 1. awk的工作原理 2. 命令格式 3. awk常见的内建变量(可直接用) 二.操作实例 1. 按行输出文本 2. 按字段输出文本 3 ...

  10. 初探Matrix Android ApkChecker

    背景 因为我所在的项目是做投放包,对安卓包的大小很敏感,经常会优化包的大小,所以想引入工具静态检测包大小,看能不能找到其中可以优化的地方,防患于未然.Matrix是微信终端自研和正在使用的一套APM( ...