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. 『德不孤』Pytest框架 — 2、Pytest的基本使用

    目录 1.Pytest安装 2.Pytest常用插件 3.Pytest运行的第一个例子 4.Pytest框架的运行方式 5.在PyCharm中以Pytest的方式运行测试用例 1.Pytest安装 C ...

  2. 676. Implement Magic Dictionary

    Implement a magic directory with buildDict, and search methods. For the method buildDict, you'll be ...

  3. 使用 ES Module 的正确姿势

    前面我们在深入理解 ES Module 中详细介绍过 ES Module 的工作原理.目前,ES Module 已经在逐步得到各大浏览器厂商以及 NodeJS 的原生支持.像 vite 等新一代的构建 ...

  4. Web播放器

    web视频播放器的使用及遇到的问题记录 TcPlayer播放器(腾讯Web超级播放器) https://cloud.tencent.com/document/product/881/20207 Ste ...

  5. 20个 CSS 快速提升技巧

    作者:web秀 http://www.javanx.cn/20190321/css-skill/ 本文涵盖了20个css技巧,可以解决许多工作中常见的问题. 1.使用CSS重置(reset) css重 ...

  6. 在build中配置resources, 来防止我们资源导出失败问题

    <!--在build中配置resources, 来防止我们资源导出失败问题--> <build> <resources> <resource> < ...

  7. 天翼网关免密改桥接&恢复出厂(含修改超密工具)

    路由/桥接模式切换 说明:默认天翼网关用的局域网ip是192.168.1.1,如果不是,则修改为局域网ip. 本机已经是桥接模式,在这里可以输入宽带账号密码转换成路由模式,两个模式之间可以互转. 恢复 ...

  8. HBuilderX频繁关闭,导致启动不了?

    根据官方给出的指南(http://ask.dcloud.net.cn/article/35583),在我的电脑打开%appdata%下面的会有HBuilderX目录,把这个目录删除或改名就可以启动了:

  9. Centos设置网络(固定IP)

    简介 设置为桥接模式,即将虚拟机的虚拟网络适配器与主机的物理网络适配器进行交接,虚拟机中的虚拟网络适配器可通过主机中的物理网络适配器直接访问到外部网络. 配置 虚拟机设置为桥接模式 进入网络配置文件, ...

  10. Log4j2日志技术总结

    前言 现在流行是SLF4j和Log4j2组合的日志技术,但为了日志技术归类,故前因后果都将做一下介绍. 市场上流行的日志框架 JUL java util logging Java开发团队开发,Jdk原 ...