反射:Assembly.GetExportedTypes要求所有程序集都存在

时间:2011-03-16 14:46:35

标签: c# .net reflection assemblies

我想使用反射来分析装配体。

具体来说,我想知道在程序集中的某个类型中是否实现了某个接口。

虽然并非所有程序集的引用都存在于机器上,这就是我需要分析它们的原因。

因此,当我致电GetTypesGetExportedTypes时,会抛出FileNotFoundException,告诉我“无法加载引用的程序集”。

这是真的,但仍然我想知道在这个程序集中实现了哪些类型

Reflector可以以某种方式做到这一点。怎么办呢?

编辑:我刚刚发现了Mono.Cecil,我想以一种简单的方式完成我的想法。但是,它是一个外部库,没有内置解决方案。

3 个答案:

答案 0 :(得分:3)

我遇到了同样的问题并且想出了这个问题:
使用Assembly.LoadFrom()代替Assembly.LoadFile()

至少对我有用! : - )

Assembly asm;
Type[] types;

asm = Assembly.LoadFile(@"C:\path\assembly.dll");
types = asm.GetTypes() // throws FileNotFoundException.

asm = Assembly.LoadFrom(@"C:\path\assembly.dll");
types = asm.GetTypes() // Works!

Assembly.GetExportedTypes()的行为与上述相同。

答案 1 :(得分:2)

CCI可能对你想要的东西有点重量级,但它可以反映出装配而不会全部加载:http://cciast.codeplex.com/

答案 2 :(得分:2)

我需要做同样的事情,经过几个小时的搜索,我遇到了this

您需要的代码位于主题的底部。它不会让你一路走来,但它至少可以让你获得一个程序集中所有类型的列表,即使没有所有的依赖项。

编辑:以下是推荐链接中使用的代码段:

AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(new AssemblyName(args.Name), AssemblyBuilderAccess.Run);
    _dumbAssemblies.Add(args.Name, ab);

    return ab;
}

private Dictionary<string, AssemblyBuilder> _dumbAssemblies;

它的作用是为每个缺少的程序集创建哑组件,这样可以避免抛出FileNotFoundException