Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Mit der Spiegelungs-API in .NET können Entwickler standardmäßig den Inhalt von Assemblys untersuchen, die in den Hauptausführungskontext geladen wurden. Manchmal ist es jedoch nicht möglich, eine Assembly in den Ausführungskontext zu laden, z. B. weil sie für eine andere Plattform oder Prozessorarchitektur kompiliert wurde oder es sich um eine Referenzassembly handelt. Mit der System.Reflection.MetadataLoadContext API können Sie solche Assemblys laden und prüfen. Assemblys, die in die MetadataLoadContext Assembly geladen werden, werden nur als Metadaten behandelt, d. h. Sie können Typen in der Assembly untersuchen, aber sie können keinen darin enthaltenen Code ausführen. Im Gegensatz zum Hauptausführungskontext lädt MetadataLoadContext Abhängigkeiten nicht automatisch aus dem aktuellen Verzeichnis; stattdessen wird die benutzerdefinierte Bindungslogik verwendet, die von der übergebenen MetadataAssemblyResolver bereitgestellt wird.
Voraussetzungen
Zum Verwenden von MetadataLoadContext installieren Sie das NuGet-Paket "System.Reflection.MetadataLoadContext". Sie wird für jedes .NET Standard 2.0-kompatible Zielframework unterstützt, z. B. .NET Core 2.0 oder .NET Framework 4.6.1.
MetadataAssemblyResolver für MetadataLoadContext erstellen
Um die MetadataLoadContext zu erstellen, benötigt man die Instanz der MetadataAssemblyResolver. Die einfachste Möglichkeit, eine anzubieten, besteht darin, das PathAssemblyResolver zu verwenden, das Assemblys aus der vorgegebenen Sammlung von Assemblypfadzeichenfolgen auflöst. Diese Sammlung sollte neben Assemblys, die Sie direkt untersuchen möchten, auch alle erforderlichen Abhängigkeiten enthalten. Wenn Sie z. B. das benutzerdefinierte Attribut in einer externen Assembly lesen möchten, sollten Sie diese Assembly einschließen, anderenfalls wird eine Ausnahme ausgelöst. In den meisten Fällen sollten Sie mindestens die Kernassembly einschließen, das heißt, die Assembly, die integrierte Systemtypen wie System.Object enthält, z. B. . . Der folgende Code zeigt, wie Sie das PathAssemblyResolver mithilfe der Auflistung erstellen, die aus der überprüften Assembly und der Core-Assembly der aktuellen Laufzeit besteht.
var resolver = new PathAssemblyResolver(new string[] { "ExampleAssembly.dll", typeof(object).Assembly.Location });
Wenn Sie Zugriff auf alle BCL-Typen benötigen, können Sie alle Laufzeitassemblys in die Auflistung aufnehmen. Der folgende Code zeigt, wie Sie die PathAssemblyResolver-Auflistung erstellen, die aus der geprüften Assembly und allen Assemblys der aktuellen Laufzeit besteht.
// Get the array of runtime assemblies.
string[] runtimeAssemblies = Directory.GetFiles(RuntimeEnvironment.GetRuntimeDirectory(), "*.dll");
// Create the list of assembly paths consisting of runtime assemblies and the inspected assembly.
var paths = new List<string>(runtimeAssemblies);
paths.Add("ExampleAssembly.dll");
// Create PathAssemblyResolver that can resolve assemblies using the created list.
var resolver = new PathAssemblyResolver(paths);
MetadataLoadContext erstellen
Um das MetadataLoadContext zu erstellen, rufen Sie seinen Konstruktor MetadataLoadContext(MetadataAssemblyResolver, String) auf und übergeben Sie das zuvor erstellte MetadataAssemblyResolver als ersten Parameter und den Kernassemblynamen als zweiten Parameter. Sie können den Hauptassemblynamen weglassen, in diesem Fall versucht der Konstruktor, Standardnamen zu verwenden: "mscorlib", "System.Runtime" oder "netstandard".
Nachdem Sie den Kontext erstellt haben, können Sie Assemblys mithilfe von Methoden wie LoadFromAssemblyPath laden. Sie können alle Spiegelungs-APIs für geladene Assemblys verwenden, mit Ausnahme von ApIs, die die Codeausführung betreffen. Die GetCustomAttributes Methode führt die Ausführung von Konstruktoren durch. Verwenden Sie daher stattdessen die GetCustomAttributesData Methode, wenn Sie benutzerdefinierte Attribute in der MetadataLoadContext untersuchen müssen.
Im folgenden Codebeispiel wird MetadataLoadContext erstellt, die Assembly hineingeladen und die Assembly-Attribute in die Konsole ausgegeben.
var mlc = new MetadataLoadContext(resolver);
using (mlc)
{
// Load assembly into MetadataLoadContext.
Assembly assembly = mlc.LoadFromAssemblyPath("ExampleAssembly.dll");
AssemblyName name = assembly.GetName();
// Print assembly attribute information.
Console.WriteLine($"{name.Name} has following attributes: ");
foreach (CustomAttributeData attr in assembly.GetCustomAttributesData())
{
try
{
Console.WriteLine(attr.AttributeType);
}
catch (FileNotFoundException ex)
{
// We are missing the required dependency assembly.
Console.WriteLine($"Error while getting attribute type: {ex.Message}");
}
}
}
Wenn Sie Typen MetadataLoadContext auf Gleichheit oder Zuweisung testen müssen, verwenden Sie nur Typobjekte, die in diesen Kontext geladen wurden. Das Mischen von MetadataLoadContext Typen mit Laufzeittypen wird nicht unterstützt. Betrachten Sie z. B. einen Typ testedType in MetadataLoadContext. Wenn Sie testen müssen, ob ein anderer Typ zugewiesen werden kann, verwenden Sie keinen Code wie typeof(MyType).IsAssignableFrom(testedType). Verwenden Sie stattdessen Code wie folgt:
Assembly matchAssembly = mlc.LoadFromAssemblyPath(typeof(MyType).Assembly.Location);
Type matchType = assembly.GetType(typeof(MyType).FullName!)!;
if (matchType.IsAssignableFrom(testedType))
{
Console.WriteLine($"{nameof(matchType)} is assignable from {nameof(testedType)}");
}
Example
Ein vollständiges Codebeispiel finden Sie im Beispiel "Inspect assembly contents using MetadataLoadContext".