For whatever reason, I can't seem to get the list of types in a referenced assembly. Not only th开发者_JAVA百科at, I can't even seem to be able to get to this referenced assembly.
I tried AppDomain.CurrentDomain.GetAssemblies()
, but it only returns assemblies that have already been loaded into memory.
I tried Assembly.GetExecutingAssembly().GetReferencedAssemblies()
, but this just returns mscorlib.
What am I missing?
Note that Assembly.GetReferencedAssemblies
only includes a particular assembly if you actually use a type in that assembly in your assembly (or a type that you use depends on a type in that assembly). It is not enough to merely include an assembly in the list of references in Visual Studio. Maybe this explains the difference in output from what you expect? I note that if you're expecting to be able to get all the assemblies that are in the list of references in Visual Studio using reflection that is impossible; the metadata for the assembly does not include any information about assemblies on which the given assembly is not dependent on.
That said, once you've retrieved a list of all the referenced assemblies something like the following should let you enumerate over all the types in those assemblies:
foreach (var assemblyName in Assembly.GetExecutingAssembly().GetReferencedAssemblies()) {
Assembly assembly = Assembly.Load(assemblyName);
foreach (var type in assembly.GetTypes()) {
Console.WriteLine(type.Name);
}
}
If you need the assemblies that are referenced in Visual Studio then you will have to parse the csproj
file. For that, check out the ItemGroup
element containing Reference
elements.
Finally, if you know where an assembly lives, you can load it using Assembly.LoadFile
and then essentially proceed as above to enumerate over the types that live in that loaded assembly.
I also landed in a situation where I had to get all the assemblies that are in the list of references in Visual Studio.
I used following work around to get it done.
var path = AppContext.BaseDirectory; // returns bin/debug path
var directory = new DirectoryInfo(path);
if (directory.Exists)
{
var dllFiles = directory.GetFiles("*.dll"); // get only assembly files from debug path
}
The method GetReferencedAssemblies basically optimize the discovery process on your assembly, skipping those assemblies that you don't have an explicit reference in your main assembly.
Let's say that you have a project B and a project C that is referencing project B. Now you create a new project A that has a reference to C(not to B)
When you call Assembly.Load("C path").GetReferenceAssemblies
it will return just B if you never made a reference to a class, enum, interface ... that was part of the C assembly.
As a workaround solution, you can create dummies instances of classes that are present in C.
Assembly.C.Class1 dummyInstance = new Assemply.C.Class1();
Personally, I used this solution in case you need to separate in a Core project all your interfaces, and in Core.Proj1 to flag your classes with the interfaces used in Core for a later discovery in your main assembly. Take in mind that reflection has an impact on the performance once you are loading multiple assemblies, so don't end with a solution making a discovery on a directory and loading all assemblies to get the types you need. So from that point, you can continue with the code that @jason suggested
foreach(var ....)
Assembly assembly = Assembly.Load(assemblyName);
foreach (var type in assembly.GetTypes()) {
Console.WriteLine(type.Name);
精彩评论