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.
Referenzassemblys sind ein spezieller Assemblytyp, der nur die minimale Menge an Metadaten enthält, die erforderlich sind, um die öffentliche API-Oberfläche der Bibliothek darzustellen. Sie beinhalten Deklarationen für alle Member, die beim Verweis auf eine Assembly in Buildtools von Bedeutung sind, schließen aber alle Memberimplementierungen und Deklarationen privater Member aus, die keine beobachtbaren Auswirkungen auf ihren API-Vertrag haben. Im Gegensatz dazu werden normale Assemblys als Implementierungsassemblys bezeichnet.
Referenzassemblys können nicht für die Ausführung geladen werden, aber sie können genauso wie Implementierungsassemblys als Compilereingabe übergeben werden. Referenzassemblys werden in der Regel mit dem Software Development Kit (SDK) einer bestimmten Plattform oder Bibliothek verteilt.
Mithilfe einer Referenzassembly können Entwickler Programme erstellen, die auf eine bestimmte Bibliotheksversion abzielen, ohne dass die vollständige Implementierungsassembly für diese Version vorhanden ist. Angenommen, Sie haben nur die neueste Version einer Bibliothek auf Ihrem Computer, aber Sie möchten ein Programm erstellen, das auf eine frühere Version dieser Bibliothek ausgerichtet ist. Wenn Sie direkt mit der Implementierungsassembly kompilieren, verwenden Sie möglicherweise versehentlich API-Member, die in der früheren Version nicht verfügbar sind. Dieser Fehler wird nur beim Testen des Programms auf dem Zielcomputer gefunden. Wenn Sie gegen die Referenzassembly für die frühere Version kompilieren, erhalten Sie sofort einen Fehler beim Kompilieren.
Eine Referenzassembly kann auch einen Vertrag darstellen, d. h. eine Gruppe von APIs, die nicht der konkreten Implementierungsassembly entsprechen. Solche Referenzassemblys, die als Vertragsassembly bezeichnet werden, können für mehrere Plattformen verwendet werden, die denselben Satz von APIs unterstützen. .NET Standard stellt z. B. die Vertragsassembly netstandard.dllbereit, die den Satz allgemeiner APIs darstellt, die zwischen verschiedenen .NET-Plattformen gemeinsam verwendet werden. Die Implementierungen dieser APIs sind in verschiedenen Assemblys auf verschiedenen Plattformen enthalten, z. B. mscorlib.dll auf .NET Framework oder System.Private.CoreLib.dll auf .NET Core. Eine Bibliothek, die auf .NET Standard ausgerichtet ist, kann auf allen Plattformen ausgeführt werden, die .NET Standard unterstützen.
Verwenden von Verweisassemblys
Um bestimmte APIs aus Ihrem Projekt zu verwenden, müssen Sie Verweise auf ihre Assemblys hinzufügen. Sie können entweder Verweise auf Implementierungsassemblys oder auf Referenzassemblys hinzufügen. Es empfiehlt es sich, Referenzassemblies zu verwenden, wann immer sie verfügbar sind. Dadurch wird sichergestellt, dass Sie nur die unterstützten API-Member in der Zielversion verwenden, die von API-Designern verwendet werden sollen. Die Verwendung der Referenzassembly stellt sicher, dass Sie keine Abhängigkeit von Implementierungsdetails eingehen.
Referenzassemblies für .NET Framework-Bibliotheken werden mit Targeting Packs verteilt. Sie können diese abrufen, indem Sie ein eigenständiges Installationsprogramm herunterladen oder eine Komponente im Visual Studio-Installationsprogramm auswählen. Weitere Informationen finden Sie unter Installieren von .NET Framework für Entwickler. Für .NET Core und .NET Standard werden Referenzassemblys bei Bedarf (über NuGet) automatisch heruntergeladen und referenziert. Für .NET Core 3.0 und höher befinden sich die Referenzassemblys für das Kernframework im Microsoft.NETCore.App.Ref-Paket (das Microsoft.NETCore.App-Paket wird stattdessen für Versionen vor 3.0 verwendet).
Wenn Sie Verweise auf .NET Framework-Assemblys in Visual Studio mithilfe des Dialogfelds " Verweis hinzufügen " hinzufügen, wählen Sie eine Assembly aus der Liste aus, und Visual Studio findet automatisch Referenzassemblys, die der in Ihrem Projekt ausgewählten Zielframeworkversion entsprechen. Dasselbe gilt für das direkte Hinzufügen von Verweisen in DAS MSBuild-Projekt mithilfe des Referenzprojektelements : Sie müssen nur den Assemblynamen und nicht den vollständigen Dateipfad angeben. Wenn Sie in der Befehlszeile Verweise auf diese Assemblys hinzufügen, indem Sie die -reference
Compileroption (in C# und visual Basic) oder die Methode in der Compilation.AddReferences Roslyn-API verwenden, müssen Sie manuell Referenzassemblydateien für die richtige Zielplattformversion angeben. .NET Framework-Referenzassemblydateien befinden sich im %ProgramFiles(x86)%\Reference Assemblies\Microsoft\Framework\. NETFramework-Verzeichnis . Für .NET Core können Sie erzwingen, dass der Veröffentlichungsvorgang Verweisassemblys für Ihre Zielplattform in das Unterverzeichnis publish/refs des Ausgabeverzeichnisses kopiert, indem Sie die PreserveCompilationContext
-Projekteigenschaft auf true
festlegen. Anschließend können Sie diese Referenzassemblydateien an den Compiler übergeben. Mithilfe DependencyContext
des Microsoft.Extensions.DependencyModel-Pakets können Sie ihre Pfade finden.
Da sie keine Implementierung enthalten, können Referenzassemblys für die Ausführung nicht geladen werden. Der Versuch, sie zu laden, führt zu System.BadImageFormatException. Wenn Sie den Inhalt einer Referenzassembly untersuchen möchten, können Sie diese (mit der Assembly.ReflectionOnlyLoad-Methode) in den auf Reflexion beschränkten Kontext in .NET Framework oder in MetadataLoadContext in .NET Core laden.
Generieren von Referenz-Assemblies
Das Erzeugen von Referenzassemblies für Ihre Bibliotheken kann nützlich sein, wenn die Nutzer Ihrer Bibliothek ihre Programme gegen viele unterschiedliche Versionen der Bibliothek erstellen müssen. Das Verteilen von Implementierungsassemblys für alle diese Versionen ist aufgrund ihrer Größe möglicherweise unpraktisch. Referenzassemblies sind kleiner, und ihre Verteilung als Teil des SDK Ihrer Bibliothek reduziert die Downloadgröße und spart Speicherplatz.
IDEs und Buildtools können auch von Referenzassemblys profitieren, um Die Erstellungszeiten für große Lösungen zu reduzieren, die aus mehreren Klassenbibliotheken bestehen. In der Regel wird in inkrementellen Buildszenarien ein Projekt neu erstellt, wenn eine seiner Eingabedateien geändert wird, einschließlich der Assemblys, von denen es abhängt. Die Implementierungsassembly ändert sich immer dann, wenn der Programmierer die Implementierung eines beliebigen Members ändert. Die Referenzassembly ändert sich nur, wenn die öffentliche API betroffen ist. Wenn Sie also die Referenzassembly als Eingabedatei anstelle der Implementierungsassembly verwenden, kann der Build des abhängigen Projekts in einigen Fällen übersprungen werden.
Sie können Referenzassemblies generieren.
- Verwenden Sie in einem MSBuild-Projekt die
ProduceReferenceAssembly
Projekteigenschaft. - Wenn Sie das Programm über die Befehlszeile kompilieren, indem Sie die Compileroptionen (
-refonly
/ ) oder (-refout
/ ) angeben . - Wenn Sie die Roslyn-API verwenden, indem Sie EmitOptions.EmitMetadataOnly auf
true
und EmitOptions.IncludePrivateMembers auffalse
in einem Objekt setzen, das an die Compilation.Emit-Methode übergeben wird.
Wenn Sie Referenzassemblys mit NuGet-Paketen verteilen möchten, müssen Sie diese im Unterverzeichnis ref\ anstelle des Unterverzeichnisses lib\ für Implementierungsassemblys einschließen.
Struktur von Verweisassemblys
Referenzassemblys sind eine Erweiterung des zugehörigen Konzepts, Assemblys mit nur Metadaten. Bei auf Metadaten beschränkten Assemblys werden die Methodentexte durch einen einzigen throw null
-Text ersetzt, sie enthalten jedoch alle Member außer anonymen Typen. Der Grund für die Verwendung von throw null
-Text (im Gegensatz zu keinem Text) besteht darin, dass PEVerify erfolgreich ausgeführt und übergeben werden kann (und damit die Vollständigkeit der Metadaten überprüft).
Verweisassemblys entfernen außerdem Metadaten (private Member) aus auf Metadaten beschränkten Assemblys:
- Eine Referenzassembly enthält nur Verweise auf das, was sie in der API-Oberfläche benötigt. Die reale Assembly enthält möglicherweise zusätzliche Verweise im Zusammenhang mit bestimmten Implementierungen. Die Referenzassembly für
class C { private void M() { dynamic d = 1; ... } }
enthält beispielsweise keine Typen, die fürdynamic
erforderlich sind. - Private Funktionsmitglieder (Methoden, Eigenschaften und Ereignisse) werden entfernt, bei denen ihre Entfernung keinen Einfluss auf die Kompilierung hat. Wenn keine InternalsVisibleTo-Attribute vorhanden sind, werden auch interne Funktionsmber entfernt.
Die Metadaten in Referenzassemblys behalten weiterhin die folgenden Informationen bei:
- Alle Typen, einschließlich privater und geschachtelter Typen.
- Alle Attribute, auch interne Attribute.
- Alle virtuellen Methoden.
- Explizite Schnittstellenimplementierungen.
- Explizit implementierte Eigenschaften und Ereignisse, da ihre Accessoren virtuell sind.
- Alle Felder von Strukturen.
Referenzassemblys enthalten ein ReferenceAssembly-Attribut auf Assemblyebene. Dieses Attribut kann in der Quelle angegeben werden; dann muss der Compiler ihn nicht synthetisieren. Aufgrund dieses Attribut verweigern Runtimes das Laden von Referenzassemblys für die Ausführung (sie können aber im reflektionsbezogenen Modus geladen werden).
Genaue Details der Referenzassemblystruktur hängen von der Compilerversion ab. Neuere Versionen können entscheiden, weitere Metadaten auszuschließen, sofern festgestellt wird, dass diese die öffentliche API-Oberfläche nicht beeinflussen.
Hinweis
Informationen in diesem Abschnitt gelten nur für Verweise auf Assemblys, die von Roslyn-Compilern ab C# Version 7.1 oder Visual Basic Version 15.3 generiert werden. Die Struktur der Referenzassemblys für .NET Framework- und .NET Core-Bibliotheken kann in einigen Details unterschiedlich sein, da sie ihren eigenen Mechanismus zum Generieren von Referenzassemblys verwenden. Sie verfügen z.B. möglicherweise über vollständig leere Methodenkörper anstelle des throw null
-Texts. Das allgemeine Prinzip gilt jedoch weiterhin: Sie verfügen nicht über verwendbare Methodenimplementierungen und enthalten Metadaten nur für Member, die aus einer öffentlichen API-Perspektive einen observablen Einfluss haben.