Dela via


Referenssammansättningar

Referenssammansättningar är en särskild typ av sammansättning som endast innehåller den minsta mängd metadata som krävs för att representera bibliotekets offentliga API-yta. De innehåller deklarationer för alla medlemmar som är viktiga när de refererar till en sammansättning i byggverktyg, men exkluderar alla medlemsimplementeringar och deklarationer av privata medlemmar som inte har någon observerbar inverkan på deras API-kontrakt. Däremot kallas regelbundna sammansättningar för implementeringssammansättningar.

Referenssammansättningar kan inte läsas in för körning, men de kan skickas som kompilatorindata på samma sätt som implementeringssammansättningar. Referenssammansättningar distribueras vanligtvis med Software Development Kit (SDK) för en viss plattform eller ett visst bibliotek.

Med hjälp av en referenssammansättning kan utvecklare skapa program som riktar sig till en specifik biblioteksversion utan att ha den fullständiga implementeringssammansättningen för den versionen. Anta att du bara har den senaste versionen av ett bibliotek på datorn, men du vill skapa ett program som är avsett för en tidigare version av biblioteket. Om du kompilerar direkt mot implementeringssammansättningen kan du oavsiktligt använda API-medlemmar som inte är tillgängliga i den tidigare versionen. Du hittar bara det här misstaget när du testar programmet på måldatorn. Om du kompilerar mot referenssammansättningen för den tidigare versionen får du omedelbart ett kompileringsfel.

En referenssammansättning kan också representera ett kontrakt, dvs. en uppsättning API:er som inte motsvarar den konkreta implementeringssammansättningen. Sådana referenssammansättningar, som kallas kontraktssammansättningen, kan användas för att rikta in sig på flera plattformar som stöder samma uppsättning API:er. Till exempel tillhandahåller .NET Standard kontraktssammansättningen, netstandard.dll, som representerar den uppsättning vanliga API:er som delas mellan olika .NET-plattformar. Implementeringarna av dessa API:er finns i olika sammansättningar på olika plattformar, till exempel mscorlib.dll på .NET Framework eller System.Private.CoreLib.dll på .NET Core. Ett bibliotek som riktar sig till .NET Standard kan köras på alla plattformar som stöder .NET Standard.

Använda referenssammansättningar

Om du vill använda vissa API:er från projektet måste du lägga till referenser till deras sammansättningar. Du kan lägga till referenser till antingen implementeringssammansättningar eller referenssammansättningar. Vi rekommenderar att du använder referenssammansättningar när de är tillgängliga. Detta säkerställer att du endast använder API-medlemmarna som stöds i målversionen, som är avsedd att användas av API-designers. Genom att använda referenssammansättningen ser du till att du inte är beroende av implementeringsinformation.

Referenssammansättningar för .NET Framework-biblioteken distribueras med målpaket. Du kan hämta dem genom att ladda ned ett fristående installationsprogram eller genom att välja en komponent i Installationsprogrammet för Visual Studio. Mer information finns i Installera .NET Framework för utvecklare. För .NET Core och .NET Standard hämtas referenssammansättningar automatiskt efter behov (via NuGet) och refereras till. För .NET Core 3.0 och senare finns referenssammansättningarna för kärnramverket i Microsoft.NETCore.App.Ref-paketet ( Microsoft.NETCore.App-paketet används i stället för versioner före 3.0).

När du lägger till referenser till .NET Framework-sammansättningar i Visual Studio med hjälp av dialogrutan Lägg till referens väljer du en sammansättning i listan, och Visual Studio hittar automatiskt referenssammansättningar som motsvarar den målramverksversion som valts i projektet. Detsamma gäller för att lägga till referenser direkt i MSBuild-projektet med hjälp av referensprojektobjektet : du behöver bara ange sammansättningsnamnet, inte den fullständiga filsökvägen. När du lägger till referenser till dessa sammansättningar på kommandoraden med hjälp av kompilatoralternativet -reference (i C# och i Visual Basic) eller med hjälp Compilation.AddReferences av metoden i Roslyn-API:et måste du manuellt ange referenssammansättningsfiler för rätt målplattformsversion. .NET Framework-referenssammansättningsfiler finns i %ProgramFiles(x86)%\Reference Assemblies\Microsoft\Framework\. NETFramework-katalog . För .NET Core kan du tvinga publiceringsåtgärden att kopiera referenssammansättningar för målplattformen till underkatalogen publish/refs för utdatakatalogen genom att ange projektegenskapen PreserveCompilationContext till true. Sedan kan du skicka dessa referenssammansättningsfiler till kompilatorn. Med hjälp av DependencyContext Microsoft.Extensions.DependencyModel-paketet kan du hitta deras sökvägar.

Eftersom de inte innehåller någon implementering kan referenssammansättningar inte läsas in för körning. Om du försöker göra det resulterar det i en System.BadImageFormatException. Om du vill undersöka innehållet i en referenssammansättning kan du läsa in det i kontexten endast reflektion i .NET Framework (med hjälp av Assembly.ReflectionOnlyLoad metoden) eller i MetadataLoadContext .NET och .NET Framework.

Generera referenssammansättningar

Att generera referenssammansättningar för dina bibliotek kan vara användbart när bibliotekskonsumenterna behöver skapa sina program mot många olika versioner av biblioteket. Distribution av implementeringssammansättningar för alla dessa versioner kan vara opraktiskt på grund av deras stora storlek. Referenssammansättningar är mindre i storlek och distributionen som en del av bibliotekets SDK minskar nedladdningsstorleken och sparar diskutrymme.

IDE:er och byggverktyg kan också dra nytta av referenssammansättningar för att minska byggtiden om det finns stora lösningar som består av flera klassbibliotek. I inkrementella byggscenarier återskapas vanligtvis ett projekt när någon av dess indatafiler ändras, inklusive de sammansättningar som det är beroende av. Implementeringssammansättningen ändras när programmeraren ändrar genomförandet av en medlem. Referenssammansättningen ändras bara när dess offentliga API påverkas. Om du använder referenssammansättningen som en indatafil i stället för implementeringssammansättningen kan du hoppa över bygget av det beroende projektet i vissa fall.

Du kan generera referenssammansättningar:

Om du vill distribuera referenssammansättningar med NuGet-paket måste du inkludera dem i underkatalogen ref\ under paketkatalogen i stället för i underkatalogen lib\ som används för implementeringssammansättningar.

Referenssammansättningsstruktur

Referenssammansättningar är en utökning av det relaterade konceptet, endast metadatasammansättningar. Endast metadatasammansättningar får sina metodkroppar ersatta med en enda throw null brödtext, men inkluderar alla medlemmar utom anonyma typer. Anledningen till att använda throw null organ (i motsats till inga kroppar) är att PEVerify kan köras och passera (vilket validerar metadatas fullständighet).

Referenssammansättningar tar ytterligare bort metadata (privata medlemmar) från metadatasammansättningar:

  • En referenssammansättning har bara referenser för vad den behöver på API-ytan. Den verkliga sammansättningen kan ha ytterligare referenser relaterade till specifika implementeringar. Referenssammansättningen för class C { private void M() { dynamic d = 1; ... } } refererar till exempel inte till några typer som krävs för dynamic.
  • Privata funktionsmedlemmar (metoder, egenskaper och händelser) tas bort i fall där borttagningen inte märkbart påverkar kompilering. Om det inte finns några InternalsVisibleTo-attribut tas även interna funktionsmedlemmar bort.

Metadata i referenssammansättningar fortsätter att behålla följande information:

  • Alla typer, inklusive privata och kapslade typer.
  • Alla attribut, även interna.
  • Alla virtuella metoder.
  • Explicita gränssnittsimplementeringar.
  • Uttryckligen implementerade egenskaper och händelser eftersom deras åtkomstorer är virtuella.
  • Alla fält i strukturer.

Referenssammansättningar innehåller ett ReferenceAssembly-attribut på sammansättningsnivå. Det här attributet kan anges i källan. behöver kompilatorn inte syntetisera den. På grund av det här attributet vägrar runtimes att läsa in referenssammansättningar för körning (men de kan läsas in i reflektionsläge).

Exakt referenssammansättningsstrukturinformation beror på kompilatorversionen. Nyare versioner kan välja att undanta fler metadata om det fastställs att det inte påverkar den offentliga API-ytan.

Kommentar

Information i det här avsnittet gäller endast för referenssammansättningar som genereras av Roslyn-kompilatorer från C#-version 7.1 eller Visual Basic version 15.3. Strukturen för referenssammansättningar för .NET Framework- och .NET Core-bibliotek kan skilja sig åt i viss information, eftersom de använder sin egen mekanism för att generera referenssammansättningar. De kan till exempel ha helt tomma metodkroppar i stället för throw null kroppen. Men den allmänna principen gäller fortfarande: de har inte användbara metodimplementeringar och innehåller endast metadata för medlemmar som har en observerbar inverkan ur ett offentligt API-perspektiv.

Se även