如何在运行时使用C#进行反射加载程序集及其所有依赖关系?
时间:2020-03-05 18:52:18 来源:igfitidea点击:
我为自己编写了一个实用程序,部分是作为学习CReflection的练习,部分是因为我实际上希望将所得的工具供自己使用。
我要做的基本上是将应用程序指向一个程序集,并选择一个给定的类,从该类中选择应作为字段包含在导出的HTML表单中的属性。然后,该表格将在我的ASP.NET MVC应用程序中用作View的开始。
当我在要使用的应用程序中使用Subsonic对象时,这应该是合理的,并且我认为,通过根据数据类型包含不同的输出HTML之类的东西,Reflection是实现此目的的方法。
但是,我正在寻找的东西似乎难以捉摸。我试图将通过OpenFileDialog选择的DLL / EXE作为起点并加载它:
String FilePath = Path.GetDirectoryName(FileName); System.Reflection.Assembly o = System.Reflection.Assembly.LoadFile(FileName);
效果很好,但是由于Subsonic生成的对象实际上充满了Subsonic.dll等中定义的对象类型,因此不会加载那些依赖对象。进入:
AssemblyName[] ReferencedAssemblies = o.GetReferencedAssemblies();
那也包含了我所期望的。但是,我试图弄清楚的是如何加载这些程序集,以便我对对象的挖掘能够正常进行。我知道,如果这些程序集位于GAC或者正在运行的可执行文件的目录中,我可以按它们的名称加载它们,但是这种用例不太可能是这种情况,这是我的主要用例。
因此,归结为如何加载给定的程序集及其所有从文件名开始的任意程序集,并生成类型,属性,方法等完全可反射的树。
我知道像Reflector这样的工具可以做到这一点,我只是找不到实现它的语法。
解决方案
回答
这里有几个选择:
- 添加到" AppDomain.AssemblyResolve"并根据请求的程序集执行另一个" LoadFile"。
- 旋转另一个以目录为基础的AppDomain,并将程序集加载到该AppDomain中。
我强烈建议我们使用选项2,因为这可能会更清洁,并允许我们在以后卸载所有这些程序集。另外,如果只需要在仅反射的上下文中考虑装配件(请参阅Assembly.ReflectionOnlyLoad
)。