C#反射之Assembly.Load,Assembly.LoadFile 与 Assembly.LoadFrom方法介绍

2025-12-13 0 756

一些关于C#反射的知识,估计也就最多达到使用API的程度,至于要深刻了解,以如今的水平估计很难作到,因此下面此篇文章,以做为一个阶段的总结缓存

对于反射的总结,我想从如下几个方面展开,首先是反射程序集,模块,类的成员以及成员的一些信息;接下来就是动态调用类的成员方法;第三个方面就动态产生程序集,模块和类以及类的成员。好了,如今就让咱们从反射各类信息开始吧安全

在C#中,咱们要使用反射,首先要搞清楚如下命名空间中几个类的关系:测试

System.Reflection命名空间.net

(1) AppDomain:应用程序域,能够将其理解为一组程序集的逻辑容器设计

(2) Assembly:程序集类code

(3) Module:模块类blog

(4) Type:使用反射获得类型信息的最核心的类字符串

他们之间是一种从属关系,也就是说,一个AppDomain能够包含N个Assembly,一个Assembly能够包含N个Module,而一个Module能够包含N个Type.部署

AppDomain这个类咱们等下再来说解。咱们先关注Assembly个类get

在程序中,若是咱们要动态加载一个程序集怎么办呢?有几种方式可使用,分别是Load、LoadFrom和LoadWithPartialName三个Assembly的静态方法.

先来说解Assembly.Load方法,该方法会有多个重载版本,其中一个就是提供程序集的详细信息,即程序集的标识,包括程序集的名称,版本,区域信息,公有密钥标记,所有都是以一个字符串的形式提供,例如:\”MyAssembly,Version=1.0.0.0,culture=zh-CN,PublicKeyToken=47887f89771bc57f”.

那么,使用Assembly.Load加载程序集的顺序是怎样的呢?首先它会去全局程序集缓存查找,而后到应用程序的根目录查找,最后会到应用程序的私有路径查找。

固然,若是你使用的是弱命名程序集,也即只给出程序集的名称,那么这个时候,CLR将不会在程序集上应用任何安全或者部署策略,并且Load也不会到全局缓存程序集中查找程序集。

测试加载弱命名程序集的例子以下:

(1) 新建一个控制台应用程序的工程,同时勾选建立解决方案

(2) 在解决方案中新建一个类库的项目,随便写一个类和一个方法

(3) 在控制台项目中,首先不添加引用,直接在Main方法中添加以下代码:

Assembly assembly = Assembly.Load(\”MyAssembly\”);

if (assembly != null)

{ Console.WriteLine(\”加载成功\”); }

执行程序,会抛出异常,说找不到该程序集。什么缘由呢?由于咱们使用的是弱命名程序集,Load方法不会去全局程序集缓存中查找,而该应用程序目录下又没有该程序集,因此程序找不到。这个时候,咱们把程序稍微改一下,不用添加代码,只需添加对MyAssembly的引用,从新运行程序,加载成功了。

接下来,咱们就要看看Load怎么加载强命名程序集了,这个步骤稍微有些复杂。仍是刚才的项目,找到MyAssembly.dll程序集所在的目录,通常在bin\”Debug目录下

(1)生成密钥对文件 sn –k MyAssemblyKey.keys

你也能够本身随便起一个密钥对文件名

(2)生成公钥文件

sn –p MyAssemblyKey.keys MyAssemblyPublicKey.PublicKey

注:查看公钥命令:sn –tp MyAssemblyPublicKey.PublicKey

(3)建立强命名程序集。

很简单,只须要在声明命名空间的那句代码上加上以下特性:

[assembly:AssemblyKeyFileAttribute(@”D:\”Test\”MyAssemblyKey.keys”)]

(4) 编译项目

(5) 将程序集添加到程序集全局缓存

gacutil –i MyAssembly.dll

这个时候,转到加载程序集的项目中,将Load方法中的参数改成”程序集名,Version=版本,culture=区域信息,PublicKeyToken=公钥“,而后再去掉对程序集的引用,咱们会发现,程序运行成功。代表Load到全局缓存区查找到了该程序集。

使用Load方法加载程序集,特别是强命名程序集,能在程序集上应用安全和部署策略,推荐使用该方法动态加载程序集,至于LoadFrom和LoadWithPartialName。

首先咱们仍是来看看LoadFrom方法,这个方法的原理是这样的:咱们若是要使用它来动态加载程序集,必须告诉它程序集的路径,也即在哪一个目录下面,CLR会去加载与你指定的路径彻底匹配的程序集。记住,当咱们指定程序集路径时,不能包括任何关于程序集强命名的信息,因此,CLR不会在咱们指定的程序集文件上应用任何策略,并且也不会去任何其余的地方搜索程序集,简言之,它就是指哪打哪,呵呵。

例如:你有个程序集在D:/Test/MyAssembly.dll,你要用Assembly.LoadFrom加载该程序集,代码就以下:

Assembly assembly = Assembly.LoadFrom(@”D:/Test/MyAssembly.dll”);

对于,LoadWithParitalName方法,推荐你们最好不要使用它,由于程序没法肯定最终要去加载哪一个程序集的版本,因此咱们这里只是简单的介绍一下它的工做原理:你能够传递一个程序集标识给它,包括程序集名称,至于其余信息是可选的(区域信息,公有密钥等),该方法执行时,会首先检查应用程序中配置文件的qualifyAssembly节点,若是存在,则把该部分名称的程序集替换成彻底的程序集标识,若是不存在,则使用程序集名称先到应用程序根目录下查找,而后是私有目录,没有找到的话,就到程序集全局缓存中查找。简单过程以下:

应用程序根目录 -> 应用程序私有目录 -> 程序集全局缓存.

Assembly.Load()方法,Assembly.LoadFrom()方法,Assembly.LoadFile()方法的区别!

1,Assembly.Load()

这个方法经过程序集的长名称(包括程序集名,版本信息,语言文化,公钥标记)来加载程序集的,会加载此程序集引用的其余程序集,通常状况下都应该优先使用 这个方法,他的执行效率比LoadFrom要高不少,并且不会形成重复加载的问题(缘由在第2点上说明)

使用这个方法的时候, CLR会应用必定的策略来查找程序集,实际上CLR按以下的顺序来定位程序集:

⑴若是程序集有强名称,在首先在全局程序集缓(GAC)中查找程序集。

⑵若是程序集的强名称没有正确指定或GAC中找不到,那么经过配置文件中的<codebase>元素指定的URL来查找

⑶若是没有指定强名称或是在GAC中找不到,CLR会探测特定的文件夹:

假设你的应用程序目录是C:/AppDir,<probing>元素中的privatePath指定了一个路径Path1,你要定位的程序集是AssemblyName.dll则CLR将按照以下顺序定位程序集

C:/AppDir/AssemblyName.dll

C:/AppDir/AssemblyName/AssemblyName.dll

C:/AppDir/Path1/AssemblyName.dll

C:/AppDir/Path1/AssemblyName/AssemblyName.dll

若是以上方法不能找到程序集,会发生编译错误,若是是动态加载程序集,会在运行时抛出异常!

2,Assembly.LoadFrom()

这个方法从指定的路径来加载程序集,实际上这个方法被调用的时候,CLR会打开这个文件,获取其中的程序集版本,语言文化,公钥标记等信息,把他们传递给 Load方法,接着,Load方法采用上面的策略来查找程序集。若是找到了程序集,会和LoadFrom方法中指定的路径作比较,若是路径相同,该程序集 会被认为是应用程序的一部分,若是路径不一样或Load方法没有找到程序集,那该程序集只是被做为一个“数据文件”来加载,不会被认为是应用程序的一部分。 这就是在第1点中提到的Load方法比LoadFrom方法的执行效率高的缘由。另外,因为可能把程序集做为“数据文件”来加载,因此使用 LoadFrom从不一样路径加载相同程序集的时候会致使重复加载。固然这个方法会加载此程序集引用的其余程序集。

3,Assembly.LoadFile()

这个方法是从指定的文件来加载程序集,和上面方法的不一样之处是这个方法不会加载此程序集引用的其余程序集!

结论:通常你们应该优先选择Load方法来加载程序集,若是遇到须要使用LoadFrom方法的时候,最好改变设计而用Load方法来代替!

另:Assembly.LoadFile 与 Assembly.LoadFrom的区别

一、Assembly.LoadFile只载入相应的dll文件,好比Assembly.LoadFile(\”abc.dll\”),则载入abc.dll,假如abc.dll中引用了def.dll的话,def.dll并不会被载入。

Assembly.LoadFrom则不同,它会载入dll文件及其引用的其余dll,好比上面的例子,def.dll也会被载入。

二、用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: 根据程序集的文件名加载程序集文件的内容。

区别:

LoadFile 方法用来来加载和检查具备相同标识但位于不一样路径中的程序集.但不会加载程序的依赖项。

LoadFrom 不能用于加载标识相同但路径不一样的程序集。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

申明:本文由第三方发布,内容仅代表作者观点,与本网站无关。对本文以及其中全部或者部分内容的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。本网发布或转载文章出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,也不代表本网对其真实性负责。

左子网 编程相关 C#反射之Assembly.Load,Assembly.LoadFile 与 Assembly.LoadFrom方法介绍 https://www.zuozi.net/36540.html

常见问题
  • 1、自动:拍下后,点击(下载)链接即可下载;2、手动:拍下后,联系卖家发放即可或者联系官方找开发者发货。
查看详情
  • 1、源码默认交易周期:手动发货商品为1-3天,并且用户付款金额将会进入平台担保直到交易完成或者3-7天即可发放,如遇纠纷无限期延长收款金额直至纠纷解决或者退款!;
查看详情
  • 1、描述:源码描述(含标题)与实际源码不一致的(例:货不对板); 2、演示:有演示站时,与实际源码小于95%一致的(但描述中有”不保证完全一样、有变化的可能性”类似显著声明的除外); 3、发货:不发货可无理由退款; 4、安装:免费提供安装服务的源码但卖家不履行的; 5、收费:价格虚标,额外收取其他费用的(但描述中有显著声明或双方交易前有商定的除外); 6、其他:如质量方面的硬性常规问题BUG等。 注:经核实符合上述任一,均支持退款,但卖家予以积极解决问题则除外。
查看详情
  • 1、左子会对双方交易的过程及交易商品的快照进行永久存档,以确保交易的真实、有效、安全! 2、左子无法对如“永久包更新”、“永久技术支持”等类似交易之后的商家承诺做担保,请买家自行鉴别; 3、在源码同时有网站演示与图片演示,且站演与图演不一致时,默认按图演作为纠纷评判依据(特别声明或有商定除外); 4、在没有”无任何正当退款依据”的前提下,商品写有”一旦售出,概不支持退款”等类似的声明,视为无效声明; 5、在未拍下前,双方在QQ上所商定的交易内容,亦可成为纠纷评判依据(商定与描述冲突时,商定为准); 6、因聊天记录可作为纠纷评判依据,故双方联系时,只与对方在左子上所留的QQ、手机号沟通,以防对方不承认自我承诺。 7、虽然交易产生纠纷的几率很小,但一定要保留如聊天记录、手机短信等这样的重要信息,以防产生纠纷时便于左子介入快速处理。
查看详情

相关文章

猜你喜欢
发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务