如何在运行时使用C#进行反射加载程序集及其所有依赖关系? [英] How Do I Load an Assembly and All of its Dependencies at Runtime in C# for Reflection?

查看:78
本文介绍了如何在运行时使用C#进行反射加载程序集及其所有依赖关系?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为自己编写一个实用程序,部分是作为学习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或正在运行的可执行文件的目录中,我可以按它们的名称加载它们,但是这种用例不太可能是这种情况,这是我的主要用例./p>

所以,归结为我如何加载给定的程序集及其所有任意程序集(从文件名开始),并生成类型,属性,方法等完全可反射的树.

我知道像Reflector这样的工具可以做到这一点,我只是找不到实现它的语法.

解决方案

此处的选项对:

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

我强烈建议您使用选项2,因为这可能会更清洁,并允许您在此之后卸载所有这些程序集.另外,如果只需要在它们之上进行反射,则考虑在仅反射的上下文中加载程序集(请参见 Assembly.ReflectionOnlyLoad ).

I'm writing a utility for myself, partly as an exercise in learning C# Reflection and partly because I actually want the resulting tool for my own use.

What I'm after is basically pointing the application at an assembly and choosing a given class from which to select properties that should be included in an exported HTML form as fields. That form will be then used in my ASP.NET MVC app as the beginning of a View.

As I'm using Subsonic objects for the applications where I want to use, this should be reasonable and I figured that, by wanting to include things like differing output HTML depending on data type, Reflection was the way to get this done.

What I'm looking for, however, seems to be elusive. I'm trying to take the DLL/EXE that's chosen through the OpenFileDialog as the starting point and load it:

String FilePath = Path.GetDirectoryName(FileName);
System.Reflection.Assembly o = System.Reflection.Assembly.LoadFile(FileName);

That works fine, but because Subsonic-generated objects actually are full of object types that are defined in Subsonic.dll, etc., those dependent objects aren't loaded. Enter:

AssemblyName[] ReferencedAssemblies = o.GetReferencedAssemblies();

That, too, contains exactly what I would expect it to. However, what I'm trying to figure out is how to load those assemblies so that my digging into my objects will work properly. I understand that if those assemblies were in the GAC or in the directory of the running executable, I could just load them by their name, but that isn't likely to be the case for this use case and it's my primary use case.

So, what it boils down to is how do I load a given assembly and all of its arbitrary assemblies starting with a filename and resulting in a completely Reflection-browsable tree of types, properties, methods, etc.

I know that tools like Reflector do this, I just can't find the syntax for getting at it.

解决方案

Couple of options here:

  1. Attach to AppDomain.AssemblyResolve and do another LoadFile based on the requested assembly.
  2. Spin up another AppDomain with the directory as its base and load the assemblies in that AppDomain.

I'd highly recommend pursuing option 2, since that will likely be cleaner and allow you to unload all those assemblies after. Also, consider loading assemblies in the reflection-only context if you only need to reflect over them (see Assembly.ReflectionOnlyLoad).

这篇关于如何在运行时使用C#进行反射加载程序集及其所有依赖关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆