如何在C#中为运行时加载程序集及其所有依赖项以进行reflection?
我正在为自己编写一个实用程序,部分原因是为了学习C#Reflection而且部分是因为我实际上想要自己使用的结果工具。
我所追求的是基本上将应用程序指向程序集并选择一个给定的类,从中选择应作为字段包含在导出的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或正在运行的可执行文件的目录中,我可以按名称加载它们,但对于这个用例而言可能不是这种情况,这是我的主要用例。
因此,它归结为如何加载给定的程序集及其所有任意程序集以文件名开头,并生成一个完全reflection可浏览的类型,属性,方法等树。
我知道像Reflector这样的工具可以做到这一点,我找不到获取它的语法。
几个选项在这里:
- 附加到
AppDomain.AssemblyResolve
并根据请求的程序集执行另一个LoadFile
。 - 以目录为基础启动另一个
AppDomain
,并在该AppDomain
加载程序集。
我强烈建议继续使用选项2,因为这样可能会更清晰,并允许您在之后卸载所有这些组件。 另外,如果只需要反映它们,请考虑在仅reflection上下文中加载程序集(请参阅Assembly.ReflectionOnlyLoad
)。
我制定了Kent Boogaart的第二个选择。 基本上我不得不:
1.)在单独的类中实现ResolveEventHandler
,inheritanceMarshalByRefObject
并添加Serializable
属性。
2.)将当前ApplicationBase
(实际上是事件处理程序的dll所在的位置)添加到AppDomain
PrivateBinPath
。
你可以在github上找到代码。