web-dev-qa-db-de.com

Wie erhält man alle Typen in einer referenzierten Assembly?

Aus irgendeinem Grund kann ich die Liste der Typen in einer Assembly, auf die verwiesen wird, nicht abrufen. Darüber hinaus scheint es mir nicht möglich zu sein, zu dieser Versammlung zu gelangen, auf die Bezug genommen wird.

Ich habe AppDomain.CurrentDomain.GetAssemblies() versucht, aber es werden nur Assemblys zurückgegeben, die bereits in den Speicher geladen wurden.

Ich habe versucht, Assembly.GetExecutingAssembly().GetReferencedAssemblies(), aber dies gibt nur mscorlib zurück.

Was vermisse ich?

32
AngryHacker

Beachten Sie, dass Assembly.GetReferencedAssemblies nur eine bestimmte Assembly enthält, wenn Sie tatsächlich einen Typ in dieser Assembly in Ihrer Assembly verwenden (oder ein Typ, den Sie verwenden, hängt von einem Typ in dieser Assembly ab). Es reicht nicht aus, nur eine Assembly in die Liste der Verweise in Visual Studio aufzunehmen. Vielleicht erklärt das den Unterschied in der Ausgabe von dem, was Sie erwarten? Wenn Sie davon ausgehen, dass Sie alle Assemblys in der Liste der Verweise in Visual Studio mit Reflektion abrufen können, ist dies nicht möglich. Die Metadaten für die Assembly enthalten keine Informationen zu Assemblys, von denen die angegebene Assembly nicht abhängig ist.

Sobald Sie jedoch eine Liste aller referenzierten Assemblys abgerufen haben, sollten Sie mit der folgenden Art über alle Typen in diesen Assemblys verfügen:

foreach (var assemblyName in Assembly.GetExecutingAssembly().GetReferencedAssemblies()) {
    Assembly assembly = Assembly.Load(assemblyName);
    foreach (var type in Assembly.GetTypes()) {
        Console.WriteLine(type.Name);
    }
}

Wenn Sie die Assemblys benötigen, auf die in Visual Studio verwiesen wird, müssen Sie die csproj-Datei parsen. Überprüfen Sie dazu das ItemGroup-Element, das Reference-Elemente enthält.

Wenn Sie wissen, wo sich eine Assembly befindet, können Sie sie schließlich mit Assembly.LoadFile laden und dann wie oben beschrieben fortfahren, um die Typen aufzulisten, die in der geladenen Assembly enthalten sind.

57
jason

Die Methode GetReferencedAssemblies optimiert im Wesentlichen den Erkennungsprozess in Ihrer Assembly, wobei die Assemblys übersprungen werden, für die in Ihrer Hauptassembly keine explizite Referenz vorhanden ist.

Nehmen wir an, Sie haben ein Projekt B und ein Projekt C, das auf Projekt B verweist. Erstellen Sie nun ein neues Projekt A, das eine Referenz auf C (nicht auf B) hat.

Wenn Sie Assembly.Load("C path").GetReferenceAssemblies aufrufen, wird nur B zurückgegeben, wenn Sie nie einen Verweis auf eine Klasse, Enumeration, Schnittstelle ... gemacht haben, die Teil der C-Assembly war.

Als Problemumgehung können Sie Dummy-Instanzen von Klassen erstellen, die in C vorhanden sind.

Assembly.C.Class1 dummyInstance = new Assemply.C.Class1();

Ich persönlich habe diese Lösung für den Fall verwendet, dass Sie in einem Core-Projekt alle Ihre Schnittstellen voneinander trennen müssen und in Core.Proj1 Ihre Klassen mit den in Core verwendeten Schnittstellen für eine spätere Erkennung in Ihrer Hauptassembly kennzeichnen. Beachten Sie, dass die Reflektion Auswirkungen auf die Leistung hat, wenn Sie mehrere Assemblys laden. Beenden Sie daher nicht, dass eine Lösung ein Verzeichnis ermittelt und alle Assemblys lädt, um die benötigten Typen zu erhalten. Von diesem Punkt aus können Sie also mit dem von @jason vorgeschlagenen Code fortfahren

foreach(var ....)
  Assembly assembly = Assembly.Load(assemblyName);
    foreach (var type in Assembly.GetTypes()) {
        Console.WriteLine(type.Name);
0
Zinov

Ich landete auch in einer Situation, in der ich alle Assemblys abrufen musste, die in der Referenzliste in Visual Studio enthalten sind. 

Ich habe die folgende Arbeit verwendet, um es zu erledigen.

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
}
0
Deepak Ageeru