当两个dll文件之间具有依赖关系时(例如A引用B),在第三方项目中通过反射去动态加载依赖另一项的dll(也就是调用A),即使这两个文件在同一目录下,也有可能会抛出could not load file or assembly的异常(如果不抛自然是最好了),下面就来介绍一下如何在第三方程序集中动态的加依赖。
首先介绍本次的主角:AppDomain.CurrentDomain.AssemblyResolve事件
该事件注册后,当发生程序集加载失败的异常时会触发该事件的实现方法。
下面正式开始
假如我新建一个类库文件A.dll,在其中添加第三方的COM引用或Nuget程序包或项目B(代码不放了,浪费时间),并生成项目。
重新新建一个程序,在该程序中将刚刚生成的dll类库文件拷贝到程序运行目录下,然后通过反射加载程序集
//A类库文件路径 var dllPath = $"{AppContext.BaseDirectory}xxx.dll"; //通过反射加载该dll var assembly = Assembly.Load(dllPath);
然后此时运行就会抛出上面的异常(或者类似的异常)
System.Refection.TargetInvocationException:“Exception has been throw by the target of an invocation.”
内部异常
FileNotFoudException:Could not load file or assembly ‘’.系统找不到指定的文件
此时我们就可以使用开始介绍过的方法来捕获一下这个异常并处理一下了。
//注册事件 AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolvel ...... //实现事件 private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { //指明丢失的依赖项的路径(例如此处放在运行目录下) var missDllPath = $"{AppContext.BaseDirectory}"; //丢失的dll的文件名 var missDllName = $"{args.Name.Remove(args.Name.IndexOf(','))}.dll" //args.Name返回的是完整的程序集信息,例如: //"MQTTnet, Version=3.0.15.0, Culture=neutral, PublicKeyToken=b69712f52770c0a7" //加载缺失dll到当前程序 return Assembly.LoadFile($"{missDllPath}{missDllName}"); }
重新运行程序,执行成功。