Indirectly accessing an assembly through reflection
OK, I have the following bit of code:
Assembly assembly = Assembly.LoadFile("W:\\AssemblyFoo.dll");
foreach (Type type in assembly.GetExportedTypes())
开发者_JAVA技巧{
foreach (object attribute in type.GetCustomAttributes(false)) //Exceptio on that line
{
string attributeString = attribute.ToString();
}
}
The code throws the following exception: Could not load file or assembly 'AssemblyBar, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
The problem is that one of the attribute is in AssemblyBar, which is referenced by AssemblyFoo, but not directly by the current's project (ProjectBaz) assembly. I'd rather avoid referencing AssemblyBar directly in ProjectBaz, since AssemblyFoo is selected by the user. What's the correct way to go about this ? I'm pretty sure I'm missing something easy.
I know it's possible since Reflector does it.
Mono's Cecil
You may circumvent the problem by not loading the assemblies through the built-in reflection facilities, using a tool like Mono.Cecil instead. I've had good experiences in applying it for analysis tasks.
From the Cecil site:
with Cecil, you can load existing managed assemblies, browse all the contained types, modify them on the fly and save back to the disk the modified assembly.
CCI Metadata
As an alternative to Cecil, you might consider CCI Metadata by Microsoft Research. I have not used that tool, so I can not comment on how it stacks up to Cecil.
Hope this helps.
You could include AssemblyBar in you bin directory so that the clr can load it.
MemberInfo.GetCustomAttributesData() was introduced in .NET 4 so that you could examine custom attributes without having to instantiate them.
UPDATE: Taking closer look at MemberInfo.GetCustomAttributesData(), although it doesn't instantiate the attributes, it still need to load the assembly. My apologies.
Another possible route to investigate would be Mono Cecil. You can load the Mono.Cecil assembly and use it with the .NET Framework, not just Mono. It is much more powerful than System.Reflection and Reflection.Emit. According to its homepage:
Cecil does not need to load the assembly or have compatible assemblies to introspect the images.
This sounds exactly like what you're trying to do.
精彩评论