System.IO.FileNotFoundException: 未能加载文件或程序集“SQLServerDAL”或它的某一个依赖项错误总结

关于这个错误,网上的版本很多,但是几乎没有几个是能从根本上解决本问题的。没有几篇博客是从反射的方法上考虑而是直接推出解决办法。但是其中有很多解决办法是不对的。从而导致我花费了大量的时间去尝试该错误的解决。最终我还是找到了一片良心文章,作者很是细心,文章写的很仔细。帮助我解决反射问题的同时让我明白了反射方法的实际运行机理。在此感谢此作者。下面是该作者文章链接,希望对大家有所帮助。
https://www.cnblogs.com/cheng2015/p/5415624.html
当我看完这篇文章之后我认为我对反射已经没有什么好写的了,但是为了加强我的记忆,以及补充一些细微之处,我打算该文章摘抄一下。
首相我们需要导入System.Reflection命名空间
然后是我们的反射语句,注意反射的返回值一般是object类型的值所以我们一般会在反射前设置强转类型。

1、反射其他程序集中的类,或者其他项目中的类

反射语句分为两部分:
第一部分加载程序集 Assembly assembly = Assembly.LoadFile(“程序集路径,不能是相对路径”); // 加载程序集(EXE 或 DLL)
第二部分创建类的实例
object obj = assembly.CreateInstance(“类的完全限定名(即包括命名空间)”); // 创建类的实例

2、获得当前项目中的类(和当前项目引用的程序集中的类)

可以为
Assembly assembly = Assembly.GetExecutingAssembly(); // 获取当前程序集
object obj = assembly.CreateInstance(“类的完全限定名(即包括命名空间)”); // 创建类的实例,返回为 object 类型,需要强制类型转换

下面讲解一下反射中常用的三个方法

关于.NET中的反射,常用的有三个方法:

Assembly.Load()
Assembly.LoadFrom()
Assembly.LoadFile()

下面说说这三个方法的区别和一些细节问题

1.Assembly.Load()

简介:
load()中接一个string类型或者AssemblyName类型作为参数买这个参数实际上是需要加载的程序集的强名称(名称,版本,语言,公钥标记)如
在这里插入图片描述
对于弱名命名的程序集。则只会有程序集名称,而不会有版本,语言和公钥标记。如DAL

细节
CLR内部普遍使用了Load()方法来加载程序集,在Load()方法的内部,CLR首先会应用这个程序集的版本绑定重定向策略,接着在GAC中查找目标程序集。如果GAC中没有找到,则会在应用程序目录和子目录中寻找(应用配置文件的codebase所指定的位置)。
如果希望加载弱命名程序集,Load()方法就不会去GAC中查找。
当Load()找到目标程序集时,就会加载它,并返回一个相应Assembly对象的引用。
当没有找到程序集时,会抛出System.IO.FileNotFoundException异常。

LoadFrom方法中强名称中公钥的获取
首先打开要获取公钥程序集的属性,然后选中标签选项,勾选为程序集签名,新建。输入文件名,密码。
在这里插入图片描述
然后点开程序集中的Assemblyinfo.cs文件
在这里插入图片描述
在改文件中加入以下语句
在这里插入图片描述
snk文件一般在程序集文件中,打开即可看到。
然后对程序进行加载
这样你的目标程序集就会成为一个有强名称的程序集。
然后打开开发人员命令提示符在开始中搜索
输入sn
然后输入sn -T 后加程序集.dll文件的绝对路径。该文件一般在程序集文件的bin文件——>debug文件中。
即可得到公钥标记

2. Assembly.LoadFrom()

简介
LoadFrom()方法可以从指定文件中加载程序集,通过查找程序集的AssemblyRef元数据表,得知所有引用和需要的程序集,然后在内部调用Load()方法进行加载。
细节
LoadFrom()首先会打开程序集文件,通过GetAssemblyName方法得到程序集名称,然后关闭文件,最后将得到的AssemblyName对象传入Load()方法中
随后,Load()方法会再次打开这个文件进行加载。所以,LoadFrom()加载一个程序集时,会多次打开文件,造成了效率低下的现象(与Load相比)。
由于内部调用了Load(),所以LoadFrom()方法还是会应用版本绑定重定向策略,也会在GAC和各个指定位置中进行查找。
LoadFrom()会直接返回Load()的结果——一个Assembly对象的引用。
如果目标程序集已经加载过,LoadFrom()不会重新进行加载。
LoadFrom支持从一个URL加载程序集(如"http://www.abc.com/test.dll"),这个程序集会被下载到用户缓存文件夹中。
从URL加载程序集时,如果计算机未联网,LoadFrom会抛出一个异常。如果IE被设置为“脱机工作”,则不会抛出异常,转而从缓存中寻找已下载的文件。

3. Assembly.LoadFile()

简介
LoadFile()从一个指定文件中加载程序集,它和LoadFrom()的不同之处在于LoadFile()不会加载目标程序集所引用和依赖的其他程序集。您需要自己控制并显示加载所有依赖的程序集
细节
LoadFile()不会解析任何依赖
LoadFile()可以多次加载同一程序集
显式加载依赖程序集的方法是,注册AppDomain的AssemblyResolve事件

区别:

LoadFile 方法用来来加载和检查具有相同标识但位于不同路径中的程序集.但不会加载程序的依赖项。
LoadFrom 不能用于加载标识相同但路径不同的程序集。
能用loadFrom的时候尽量使用load

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章