13

我正在为自己编写一个实用程序,部分是作为学习 C# 反射的练习,部分是因为我实际上想要生成的工具供我自己使用。

我所追求的基本上是将应用程序指向一个程序集并选择一个给定的类,从中选择应该作为字段包含在导出的 HTML 表单中的属性。然后,该表单将在我的 ASP.NET MVC 应用程序中用作视图的开头。

由于我将 Subsonic 对象用于我想要使用的应用程序,这应该是合理的,我认为,通过想要包含诸如根据数据类型而不同的输出 HTML 之类的东西,反射是完成这项工作的方法。

然而,我正在寻找的东西似乎难以捉摸。我试图将通过 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 这样的工具可以做到这一点,我只是找不到语法。

4

2 回答 2

13

这里有几个选项:

  1. 根据请求的程序集附加AppDomain.AssemblyResolve并执行另一个。LoadFile
  2. 以该目录为基础启动另一个AppDomain并加载其中的程序集AppDomain

我强烈建议采用选项 2,因为这可能会更干净,并且允许您在之后卸载所有这些程序集。此外,如果您只需要对它们进行反射,请考虑在仅反射上下文中加载程序集(请参阅 参考资料Assembly.ReflectionOnlyLoad)。

于 2008-09-12T15:13:56.800 回答
5

我制定了Kent Boogaart的第二个选项。基本上我必须:

1.)ResolveEventHandler在一个单独的类中实现,继承MarshalByRefObject并添加Serializable属性。

2.) 将当前的ApplicationBase,本质上是事件处理程序的 dll 所在的位置,添加到AppDomain PrivateBinPath.

你可以在github上找到代码。

于 2016-05-05T21:54:53.340 回答