Wie bekomme ich C # .Net Assembly nach Namen?

88

Gibt es so etwas wie:

AppDomain.CurrentDomain.GetAssemblyByName("TheAssemblyName")

also anstatt durchzuschleifen AppDomain.CurrentDomain.GetAssemblies() , könnten wir einfach die spezifische Baugruppe direkt erhalten.

Jronny
quelle

Antworten:

104

Haben Sie versucht, Assembly.Load (...) zu betrachten ?

Cyberzed
quelle
4
Für diejenigen, die sich fragen, wirft dies, System.IO.FileNotFoundExceptionwenn die Baugruppe nicht geladen werden konnte.
Rudey
72

Ich habe mit LINQ gelöst

Assembly GetAssemblyByName(string name)
{
    return AppDomain.CurrentDomain.GetAssemblies().
           SingleOrDefault(assembly => assembly.GetName().Name == name);
}
Fabio
quelle
7
Dies funktioniert nur, wenn die betreffende Baugruppe geladen ist.
Kann
17

Es hängt davon ab, was Sie erreichen wollen.

Wenn Sie nur die Baugruppe erhalten möchten, sollten Sie anrufen System.Reflection.Assembly.Load()(wie bereits erwähnt). Dies liegt daran, dass .NET automatisch überprüft, ob die Assembly bereits in die aktuelle AppDomain geladen wurde, und sie dann nicht erneut lädt, wenn dies der Fall war.

Wenn Sie nur versuchen zu überprüfen, ob die Baugruppe geladen wurde oder nicht (möglicherweise aus diagnostischen Gründen), müssen Sie alle geladenen Baugruppen durchlaufen.

Ein weiterer Grund, warum Sie eine Schleife durchführen möchten, besteht darin, dass Sie nur einige der Assembly-Informationen kennen (z. B. sind Sie sich der Version nicht sicher). Das heißt, Sie wissen genug, um "es zu erkennen, wenn Sie es sehen", aber nicht genug, um es zu laden. Das ist jedoch ein ziemlich dunkles und unwahrscheinliches Szenario.

EMP
quelle
System.Reflection.Assembly.Load () ist genauso perfekt wie das, was ich brauche.
Jronny
9

Für diejenigen, die nur auf die Metadaten (Version usw.) der Assembly zugreifen müssen, lesen Sie Assembly.ReflectionOnlyLoad (Name), mit dem nur die Metadaten geladen werden können, wodurch möglicherweise Speicher und E / A eingespart werden.

Mathieu Frenette
quelle
2
@ erik-reppen: Laut MS-Dokumenten ist es in früheren Versionen verfügbar. Ich benutze es in einer 3.5 App: msdn.microsoft.com/en-us/library/0et80c7k(v=vs.100).aspx
Codenheim
6

Wenn dies eine Assembly ist, auf die Sie verwiesen haben, schreibe ich gerne eine Klasse wie die folgende:

namespace MyLibrary {
   public static class MyLibraryAssembly {
      public static readonly Assembly Value = typeof(MyLibraryAssembly).Assembly;
   }
}

und wann immer Sie einen Verweis auf diese Baugruppe benötigen:

var assembly = MyLibraryAssembly.Value;
Dave Cousineau
quelle
Dies ist eine sehr saubere Lösung, nach der ich immer gesucht habe! Ich kann es so benutzen:options.RegisterFromAssembly(Application.AssemblyReference.Value)
Alielson Piffer
3

Sie können eine Erweiterungsmethode schreiben, die genau das tut, was Sie benötigen.

Diese Methode listet geladene Assemblys nur auf . Wenn Sie sie möglicherweise laden müssen, verwenden Sie sie Assembly.Loadaus der akzeptierten Antwort.

public static class AppDomainExtensions
{
    public static Assembly GetAssemblyByName(this AppDomain domain, string assemblyName)
    {
        return domain.GetAssemblies().FirstOrDefault(a => a.GetName().Name == assemblyName);
    }
}

Dann rufen Sie diese Methode in einer AppDomain wie folgt auf:

Assembly a = AppDomain.CurrentDomain.GetAssemblyByName("SomeAssembly")

Wenn SomeAssembly in die aktuelle AppDomain geladen wird, gibt die Methode diese zurück, andernfalls wird sie zurückgegeben null.

Marcell Toth
quelle
Ich habe GetAssemblyByName ()
Ziggler
2

Schauen Sie sich die System.Reflection.Assembly-Klasse an, insbesondere die Load-Methode: MSDN

Maximilian Mayerl
quelle