通过反射间接访问装配

时间:2010-11-24 03:03:46

标签: c# reflection

好的,我有以下代码:

Assembly assembly = Assembly.LoadFile("W:\\AssemblyFoo.dll");

foreach (Type type in assembly.GetExportedTypes())
{
    foreach (object attribute in type.GetCustomAttributes(false)) //Exceptio on that line
    {
        string attributeString = attribute.ToString();
    }
}

代码抛出以下异常:无法加载文件或程序集'AssemblyBar,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'或其依赖项之一。系统找不到指定的文件。

问题是其中一个属性在AssemblyBar中,由AssemblyFoo引用,但不是由当前的项目(ProjectBaz)程序集直接引用。我宁愿避免直接在ProjectBaz中引用AssemblyBar,因为用户选择了AssemblyFoo。什么是正确的方法去做?我很确定我错过了一些简单的东西。

我知道,因为Reflector可以做到这一点。

3 个答案:

答案 0 :(得分:2)

Mono's Cecil

您可以通过不通过内置反射加载程序集来避免此问题 设施,使用Mono.Cecil之类的工具。我在将它应用于分析任务方面有很好的经验。

来自塞西尔网站:

  

使用Cecil,您可以加载现有的   托管程序集,浏览所有   包含类型,修改它们   飞行并保存回磁盘   修改过的装配。

CCI元数据

作为Cecil的替代方案,您可以考虑CCI Metadata by Microsoft Research。我没有使用过那个工具,所以我无法评论它如何叠加到Cecil。

希望这有帮助。

答案 1 :(得分:0)

您可以在bin目录中包含AssemblyBar,以便clr可以加载它。

答案 2 :(得分:0)

MemberInfo.GetCustomAttributesData()是在.NET 4中引入的,因此您可以检查自定义属性,而无需实例化它们。

更新:仔细查看MemberInfo.GetCustomAttributesData(),虽然它没有实例化属性,但它仍然需要加载程序集。道歉。

另一种可能的调查途径是Mono Cecil。您可以加载Mono.Cecil程序集并将其与.NET Framework一起使用,而不仅仅是Mono。它比System.Reflection和Reflection.Emit强大得多。根据其主页:

  

Cecil不需要加载程序集或具有兼容的程序集来内省图像。

这听起来就像你想要的那样。