System.Runtime.Versioning.ComponentGuaranteesAttribute-klassen

Anmärkning

Den här artikeln innehåller ytterligare kommentarer till referensdokumentationen för det här API:et.

ComponentGuaranteesAttribute Används av utvecklare av komponenter och klassbibliotek för att ange vilken kompatibilitetsnivå som användarna av deras bibliotek kan förvänta sig i flera versioner. Den anger garantinivån för att en framtida version av biblioteket eller komponenten inte kommer att bryta en befintlig klient. Klienter kan sedan använda ComponentGuaranteesAttribute som ett stöd för att utforma sina egna gränssnitt för att säkerställa stabilitet mellan olika versioner.

Anmärkning

CLR (Common Language Runtime) använder inte det här attributet på något sätt. Dess värde ligger i att formellt dokumentera komponentförfattarens avsikt. Kompileringsverktyg kan också använda dessa deklarationer för att identifiera kompileringsfel som annars skulle bryta den deklarerade garantin.

Kompatibilitetsnivåer

Stöder ComponentGuaranteesAttribute följande kompatibilitetsnivåer, som representeras av medlemmar i ComponentGuaranteesOptions uppräkningen:

  • Ingen version-till-version-kompatibilitet (ComponentGuaranteesOptions.None). Klienten kan förvänta sig att framtida versioner kommer att bryta den befintliga klienten. Mer information finns i avsnittet Ingen kompatibilitet senare i den här artikeln.

  • Version-till-version kompatibilitet sida vid sida (ComponentGuaranteesOptions.SideBySide). Komponenten har testats för att fungera när mer än en version av sammansättningen läses in i samma programdomän. I allmänhet kan framtida versioner bryta kompatibiliteten. Men när icke-bakåtkompatibla ändringar görs ändras inte den gamla versionen utan samexisterar med den nya versionen. Sida vid sida-körning är det förväntade sättet att få befintliga klienter att fungera när brytande ändringar görs. Mer information finns i avsnittet Sida vid sida-kompatibilitet senare i den här artikeln.

  • Stabil version-till-version-kompatibilitet (ComponentGuaranteesOptions.Stable). Framtida versioner bör inte störa klienten, och parallell körning ska inte behövas. Men om klienten av misstag blir trasig kan det vara möjligt att använda körning sida vid sida för att åtgärda problemet. Mer information finns i avsnittet Stabil kompatibilitet .

  • Exchange-kompatibilitet från version till version (ComponentGuaranteesOptions.Exchange). Det läggs särskild omsorg vid att se till att framtida versioner inte skadar klienten. Klienten bör endast använda dessa typer i signaturen för gränssnitt som används för kommunikation med andra sammansättningar som distribueras oberoende av varandra. Endast en version av dessa typer förväntas finnas i en viss programdomän, vilket innebär att om en klient går sönder kan körningen sida vid sida inte åtgärda kompatibilitetsproblemet. Mer information finns i avsnittet Exchange-typkompatibilitet .

I följande avsnitt beskrivs varje garantinivå i detalj.

Ingen kompatibilitet

Att markera en komponent som ComponentGuaranteesOptions.None anger att providern inte ger några garantier för kompatibilitet. Klienter bör undvika att ta några beroenden på de exponerade gränssnitten. Den här kompatibilitetsnivån är användbar för typer som är experimentella eller offentligt exponerade men som endast är avsedda för komponenter som alltid uppdateras samtidigt. None anger uttryckligen att den här komponenten inte ska användas av externa komponenter.

Kompatibilitet sida vid sida

Markera en komponent som ComponentGuaranteesOptions.SideBySide anger att komponenten har testats för att fungera när mer än en version av sammansättningen läses in i samma programdomän. Icke-bakåtkompatibla ändringar tillåts så länge de görs i komponenten som har ett högre versionsnummer. Komponenter som är bundna till en gammal version av sammansättningen förväntas fortsätta att binda till den gamla versionen, och andra komponenter kan binda till den nya versionen. Det går också att uppdatera en komponent som deklareras vara SideBySide genom att destruktivt ändra den gamla versionen.

Stabil kompatibilitet

Markera en typ som ComponentGuaranteesOptions.Stable anger att typen ska vara stabil mellan olika versioner. Det kan dock också vara möjligt för sida-vid-sida-versioner av en stabil typ att finnas i samma programdomän.

Stabila typer har en hög standard för binär kompatibilitet. Därför bör leverantörer undvika att göra förändringar som bryter stabila typer. Följande typer av ändringar är godtagbara:

  • Lägga till privata instansfält i eller ta bort fält från en typ, så länge detta inte bryter serialiseringsformatet.
  • Ändra en icke-serialiserbar typ till en serialiserbar typ. (En serialiserbar typ kan dock inte ändras till en typ som inte kan serialiseras.)
  • Utlöser nya, mer härledda undantag från en metod.
  • Förbättra prestanda för en metod.
  • Ändra intervallet för returvärden, så länge ändringen inte påverkar majoriteten av klienterna negativt.
  • Åtgärda allvarliga buggar, om affärsmotiveringen är hög och antalet klienter som påverkas negativt är lågt.

Eftersom nya versioner av stabila komponenter inte förväntas bryta befintliga klienter behövs vanligtvis bara en version av en stabil komponent i en programdomän. Detta är dock inte ett krav eftersom stabila typer inte används som välkända utbytestyper som alla komponenter är överens om. Om en ny version av en stabil komponent oavsiktligt bryter någon komponent, och om andra komponenter behöver den nya versionen, kan det därför vara möjligt att åtgärda problemet genom att läsa in både den gamla och den nya komponenten.

Stable ger en starkare version kompatibilitetsgaranti än None. Det är en vanlig standard för komponenter med flera versioner.

Stable kan kombineras med SideBySide, som anger att komponenten inte bryter kompatibiliteten men testas för att fungera när mer än en version läses in i en viss programdomän.

När en typ eller metod har markerats som Stablekan den uppgraderas till Exchange. Det kan dock inte nedgraderas till None.

Exchange-typkompatibilitet

Att markera en typ som ComponentGuaranteesOptions.Exchange ger en starkare version kompatibilitetsgaranti än Stable, och bör tillämpas på den mest stabila av alla typer. Dessa typer är avsedda att användas för utbyte mellan oberoende byggda komponenter över alla komponentgränser i både tid (vilken som helst version av CLR eller någon version av en komponent eller applikation) och rum (över processer, över CLR inom en process, över applikationsdomäner inom en CLR). Om en icke-bakåtkompatibel ändring görs i en växeltyp går det inte att lösa problemet genom att ladda flera versioner av typen.

Exchange-typer bör endast ändras när ett problem är mycket allvarligt (till exempel ett allvarligt säkerhetsproblem) eller sannolikheten för avbrott är mycket låg (dvs. om beteendet redan bröts på ett slumpmässigt sätt som koden inte kunde tänkas ha tagit ett beroende av). Du kan göra följande typer av ändringar i en exchange-typ:

  • Lägg till arv av nya gränssnittsdefinitioner.

  • Lägg till nya privata metoder som implementerar metoderna för nyligen ärvda gränssnittsdefinitioner.

  • Lägg till nya statiska fält.

  • Lägg till nya statiska metoder.

  • Lägg till nya metoder för icke-virtuella instanser.

Följande betraktas som oförenliga ändringar och är inte tillåtna för primitiva typer:

  • Ändra serialiseringsformat. Versionstolerant serialisering krävs.

  • Lägga till eller ta bort privata instansfält. Detta riskerar att ändra serialiseringsformatet för typen och bryta klientkoden som använder reflektion.

  • Ändra serialiserbarheten hos en typ. En icke-serialiserbar typ kan inte göras serialiserbar och vice versa.

  • Utlöser olika undantag från en metod.

  • Ändra intervallet för en metods returvärden, såvida inte medlemsdefinitionen ger den här möjligheten och tydligt anger hur klienter ska hantera okända värden.

  • Åtgärda de flesta buggar. Konsumenter av typen förlitar sig på det befintliga beteendet.

När en komponent, typ eller medlem har markerats med Exchange garantin kan den inte ändras till antingen Stable eller None.

Vanligtvis är exchange-typerna de grundläggande typerna (till exempel Int32 och String i .NET) och gränssnitt (till exempel IList<T>, IEnumerable<T>och IComparable<T>) som ofta används i offentliga gränssnitt.

Exchange-typer kan offentligt exponera endast andra typer som också är markerade med Exchange kompatibilitet. Dessutom kan exchange-typer inte bero på beteendet för Windows-API:er som är benägna att ändras.

Komponentgarantier

Följande tabell visar hur en komponents egenskaper och användning påverkar dess kompatibilitetsgaranti.

Komponentegenskaper Utbyte Stabil Sida vid sida Ingen
Kan användas i gränssnitt mellan komponenter som uppdateras självständigt. Y N N N
Kan användas (privat) av en sammansättning som versioner oberoende av varandra. Y Y Y N
Kan ha flera versioner i en enda programdomän. N Y Y Y
Kan göra störande ändringar N N Y Y
Testad för att se till att flera versioner av programmodulen kan laddas samtidigt. N N Y N
Kan göra oförenliga ändringar på plats. N N N Y
Kan göra mycket säkra icke-brytande underhållsändringar på plats. Y Y Y Y

Tillämpa attributet

Du kan applicera ComponentGuaranteesAttribute på en sammansättning, en typ eller en typmedlem. Dess tillämpning är hierarkisk. Som standard definieras garantin av attributets Guarantees-egenskap på sammansättningsnivå, vilket definierar garantin för alla typer i sammansättningen och alla medlemmar i dessa typer. Om garantin tillämpas på typen gäller den som standard även för varje medlem av typen.

Denna ärvda garanti kan åsidosättas genom att tillämpa ComponentGuaranteesAttribute på enskilda typer och typmedlemmar. Garantier som åsidosätter standardvärdet kan dock bara försvaga garantin. de kan inte stärka den. Om en sammansättning till exempel har markerats med None garantin har dess typer och medlemmar ingen kompatibilitetsgaranti och alla andra garantier som tillämpas på typer eller medlemmar i sammansättningen ignoreras.

Testa garantin

Egenskapen Guarantees returnerar en medlem i ComponentGuaranteesOptions uppräkningen, som är markerad med attributet FlagsAttribute . Det innebär att du bör testa för den flagga som du är intresserad av genom att maskera bort potentiellt okända flaggor. I följande exempel testas till exempel om en typ är markerad som Stable.

// Test whether guarantee is Stable.
if ((guarantee & ComponentGuaranteesOptions.Stable) == ComponentGuaranteesOptions.Stable)
   Console.WriteLine($"{typ.Name} is marked as {guarantee}.");
' Test whether guarantee is Stable.
If (guarantee And ComponentGuaranteesOptions.Stable) = ComponentGuaranteesOptions.Stable Then
   Console.WriteLine("{0} is marked as {1}.", typ.Name, guarantee)
End If

I följande exempel testas om en typ är markerad som Stable eller Exchange.

// Test whether guarantee is Stable or Exchange.
if ((guarantee & (ComponentGuaranteesOptions.Stable | ComponentGuaranteesOptions.Exchange)) > 0)
   Console.WriteLine($"{typ.Name} is marked as Stable or Exchange.");
' Test whether guarantee is Stable or Exchange.
If (guarantee And (ComponentGuaranteesOptions.Stable Or ComponentGuaranteesOptions.Exchange)) > 0 Then
   Console.WriteLine("{0} is marked as Stable or Exchange.", typ.Name, guarantee)
End If

I följande exempel testas om en typ är markerad som None (det vill säga varken Stable eller Exchange).

// Test whether there is no guarantee (neither Stable nor Exchange).
if ((guarantee & (ComponentGuaranteesOptions.Stable | ComponentGuaranteesOptions.Exchange)) == 0)
   Console.WriteLine($"{typ.Name} has no compatibility guarantee.");
' Test whether there is no guarantee (neither Stable nor Exchange).
If (guarantee And (ComponentGuaranteesOptions.Stable Or ComponentGuaranteesOptions.Exchange)) = 0 Then
   Console.WriteLine("{0} has no compatibility guarantee.", typ.Name, guarantee)
End If