Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Opmerking
In dit artikel vindt u aanvullende opmerkingen in de referentiedocumentatie voor deze API.
Het ComponentGuaranteesAttribute wordt gebruikt door ontwikkelaars van onderdelen en klassebibliotheken om het compatibiliteitsniveau aan te geven dat consumenten van hun bibliotheken in meerdere versies kunnen verwachten. Het geeft het garantieniveau aan dat een toekomstige versie van de bibliotheek of het onderdeel een bestaande client niet onderbreekt. Clients kunnen vervolgens de hulp gebruiken bij het ComponentGuaranteesAttribute ontwerpen van hun eigen interfaces om stabiliteit in verschillende versies te garanderen.
Opmerking
De COMMON Language Runtime (CLR) gebruikt dit kenmerk op geen enkele manier. De waarde ervan ligt in het formeel documenteren van de intentie van de auteur van het onderdeel. Hulpprogramma's voor compileren kunnen deze declaraties ook gebruiken om compilatiefouten te detecteren die anders de gedeclareerde garantie zouden verbreken.
Compatibiliteitsniveaus
De ComponentGuaranteesAttribute ondersteunt de volgende compatibiliteitsniveaus, die worden vertegenwoordigd door leden van de ComponentGuaranteesOptions opsomming:
Geen compatibiliteit tussen versies (ComponentGuaranteesOptions.None). De client kan verwachten dat toekomstige versies de bestaande client breken. Zie de sectie Geen compatibiliteit verderop in dit artikel voor meer informatie.
Versie-op-versie compatibiliteit naast elkaar (ComponentGuaranteesOptions.SideBySide). Het onderdeel is getest om te werken wanneer meer dan één versie van de assembly wordt geladen in hetzelfde toepassingsdomein. Over het algemeen kunnen toekomstige versies de compatibiliteit verbreken. Wanneer er echter wijzigingen worden aangebracht die fouten veroorzaken, wordt de oude versie niet gewijzigd, maar bestaat deze naast de nieuwe versie. Parallelle uitvoering is de verwachte manier om bestaande clients te laten werken wanneer ingrijpende wijzigingen worden doorgevoerd. Zie de sectie Compatibiliteit naast elkaar verderop in dit artikel voor meer informatie.
Stabiele versie-naar-versie-compatibiliteit (ComponentGuaranteesOptions.Stable). Toekomstige versies mogen de client niet verstoren en gelijktijdige uitvoering mag niet nodig zijn. Als de client echter per ongeluk kapot is, is het mogelijk om parallelle uitvoering te gebruiken om het probleem op te lossen. Zie de sectie Stabiele compatibiliteit voor meer informatie.
Compatibiliteit van Exchange-versie-naar-versie (ComponentGuaranteesOptions.Exchange). Er wordt buitengewone zorg besteed aan ervoor te zorgen dat toekomstige versies de client geen schade toebrengen. De client mag alleen deze typen gebruiken in de handtekening van interfaces die worden gebruikt voor communicatie met andere assembly's die onafhankelijk van elkaar worden geïmplementeerd. Er wordt verwacht dat slechts één versie van deze typen zich in een bepaald toepassingsdomein bevindt. Dit betekent dat als een client kapotgaat, parallelle uitvoering het compatibiliteitsprobleem niet kan oplossen. Zie de sectie Compatibiliteit van Exchange-typen voor meer informatie.
In de volgende secties wordt elk garantieniveau uitvoeriger besproken.
Geen compatibiliteit
Het markeren van een onderdeel zoals ComponentGuaranteesOptions.None geeft aan dat de provider geen garanties geeft over compatibiliteit. Clients moeten voorkomen dat er afhankelijkheden worden gemaakt van de blootgestelde interfaces. Dit compatibiliteitsniveau is handig voor typen die experimenteel zijn of openbaar worden weergegeven, maar zijn alleen bedoeld voor onderdelen die altijd tegelijkertijd worden bijgewerkt. None geeft expliciet aan dat dit onderdeel niet door externe onderdelen moet worden gebruikt.
Zij-aan-zij compatibiliteit
Als u een onderdeel markeert zoals ComponentGuaranteesOptions.SideBySide wordt aangegeven dat het onderdeel is getest om te werken wanneer meer dan één versie van de assembly in hetzelfde toepassingsdomein wordt geladen. Belangrijke wijzigingen zijn toegestaan zolang ze worden aangebracht in de assembly met het grotere versienummer. Onderdelen die zijn gebonden aan een oude versie van de assembly, blijven naar verwachting binden aan de oude versie en andere onderdelen kunnen worden verbonden met de nieuwe versie. Het is ook mogelijk om een onderdeel bij te werken dat is gedeclareerd SideBySide door de oude versie destructief te wijzigen.
Stabiele compatibiliteit
Het markeren van een type zoals ComponentGuaranteesOptions.Stable geeft aan dat het type stabiel moet blijven in verschillende versies. Het kan echter ook mogelijk zijn voor naast elkaar bestaande versies van een stabiel type in hetzelfde toepassingsdomein.
Stabiele typen onderhouden een hoge binaire compatibiliteitsbalk. Hierdoor moeten providers vermijden om brekende wijzigingen aan stabiele typen aan te brengen. De volgende soorten wijzigingen zijn acceptabel:
- Het toevoegen van privé-exemplaarvelden aan of het verwijderen van velden uit een type, zolang dit de serialisatie-indeling niet onderbreekt.
- Een niet-serialiseerbare type wijzigen in een serialiseerbare type. (Een serialiseerbaar type kan echter niet worden gewijzigd in een niet-serialiseerbare type.)
- Nieuwe, meer afgeleide uitzonderingen genereren van een methode.
- De prestaties van een methode verbeteren.
- Het bereik van retourwaarden wijzigen, zolang de wijziging geen negatieve invloed heeft op het merendeel van de clients.
- Het oplossen van ernstige bugs, als de zakelijke reden hoog is en het aantal nadelig beïnvloede clients laag is.
Omdat nieuwe versies van stabiele onderdelen niet naar verwachting bestaande clients breken, is over het algemeen slechts één versie van een stabiel onderdeel nodig in een toepassingsdomein. Dit is echter geen vereiste, omdat stabiele typen niet worden gebruikt als bekende uitwisselingstypen waarover alle onderdelen het eens zijn. Als een nieuwe versie van een stabiel onderdeel per ongeluk een onderdeel onderbreekt en als andere onderdelen de nieuwe versie nodig hebben, is het mogelijk om het probleem op te lossen door zowel het oude als het nieuwe onderdeel te laden.
Stable biedt een sterkere versiecompatibiliteitsgarantie dan None. Het is een algemene standaardinstelling voor onderdelen met meerdere versies.
Stable kan worden gecombineerd met SideBySide, wat aangeeft dat het onderdeel de compatibiliteit niet onderbreekt, maar wordt getest om te werken wanneer meer dan één versie in een bepaald toepassingsdomein wordt geladen.
Nadat een type of methode is gemarkeerd als Stable, kan deze worden geüpgraded naar Exchange. Het kan echter niet worden gedowngraded naar None.
Compatibiliteit van Exchange-typen
Het markeren van een type als ComponentGuaranteesOptions.Exchange biedt een sterkere versiecompatibiliteitsgarantie dan Stable, en moet worden toegepast op de meest stabiele van alle typen. Deze typen zijn bedoeld om te worden gebruikt voor uitwisseling tussen onafhankelijk gebouwde onderdelen over alle onderdeelgrenzen in beide tijden (elke versie van de CLR of elke versie van een onderdeel of toepassing) en ruimte (cross-process, cross-CLR in één proces, domein voor meerdere toepassingen in één CLR). Als er een breaking change wordt gemaakt in een exchange-type, is het onmogelijk om het probleem op te lossen door meerdere versies van het type te laden.
Exchange-typen moeten alleen worden gewijzigd wanneer een probleem zeer ernstig is (zoals een ernstig beveiligingsprobleem) of de waarschijnlijkheid van onderbrekingen zeer laag is (dat wil gezegd, als het gedrag al op een willekeurige manier is verbroken waarop code mogelijk geen afhankelijkheid had kunnen hebben). U kunt de volgende soorten wijzigingen aanbrengen in een exchange-type:
Overname van nieuwe interfacedefinities toevoegen.
Voeg nieuwe privémethoden toe waarmee de methoden van nieuw overgenomen interfacedefinities worden geïmplementeerd.
Nieuwe statische velden toevoegen.
Nieuwe statische methoden toevoegen.
Voeg nieuwe niet-virtuele exemplaarmethoden toe.
De volgende worden beschouwd als belangrijke wijzigingen die niet zijn toegestaan voor primitieve typen:
Serialisatie-indelingen wijzigen. Versietolerante serialisatie is vereist.
Velden voor private instanties toevoegen of verwijderen. Door het wijzigen van de serialisatie-indeling van het type loopt u het risico dat de clientcode die gebruikmaakt van reflectie wordt beschadigd.
De serialiseerbaarheid van een type wijzigen. Een niet-serialiseerbare type kan mogelijk niet serialiseerbaar worden gemaakt en omgekeerd.
Het werpen van verschillende uitzonderingen vanuit een methode.
Het wijzigen van het bereik van de retourwaarden van een methode wordt afgeraden, tenzij de definitie van het lid deze mogelijkheid noemt en duidelijk aangeeft hoe gebruikers onbekende waarden moeten verwerken.
De meeste bugs oplossen. Consumenten van het type zijn afhankelijk van het bestaande gedrag.
Nadat een onderdeel, type of lid is gemarkeerd met de Exchange garantie, kan het niet worden gewijzigd in Stable of None.
Exchange-typen zijn doorgaans de basistypen (zoals Int32 en String in .NET) en interfaces (zoals IList<T>IEnumerable<T>, en IComparable<T>) die vaak worden gebruikt in openbare interfaces.
Exchange-typen kunnen alleen andere typen openbaar maken die ook zijn gemarkeerd met Exchange compatibiliteit. Bovendien kunnen exchange-typen niet afhankelijk zijn van het gedrag van Windows-API's die gevoelig zijn voor wijzigingen.
Garanties voor onderdelen
De volgende tabel geeft aan hoe de kenmerken en het gebruik van een onderdeel van invloed zijn op de compatibiliteitsgarantie.
| Onderdeelkenmerken | Uitwisseling | Stabiel | Naast elkaar | Geen |
|---|---|---|---|---|
| Kan worden gebruikt in interfaces tussen componenten die versie-onafhankelijk zijn. | Ja | N | N | N |
| Kan (privé) worden gebruikt door een assembly die onafhankelijk versies heeft. | Ja | Ja | Ja | N |
| Kan meerdere versies in één toepassingsdomein hebben. | N | Ja | Ja | Ja |
| Kan belangrijke wijzigingen aanbrengen | N | N | Ja | Ja |
| Getest om er zeker van te zijn dat meerdere versies van de assembly samen kunnen worden geladen. | N | N | Ja | N |
| Kan ontwrichtende wijzigingen ter plekke aanbrengen. | N | N | N | Ja |
| Kan zeer veilige niet-brekende onderhoudswijzigingen aanbrengen. | Ja | Ja | Ja | Ja |
Het kenmerk toepassen
U kunt de ComponentGuaranteesAttribute toepassing toepassen op een assembly, een type of een typelid. De toepassing is hiërarchisch. Dit is standaard: de garantie die is gedefinieerd door de eigenschap Guarantees van het kenmerk op assemblyniveau, bepaalt de garantie van alle typen in de assembly en alle leden in die typen. Als de garantie op het type wordt toegepast, geldt deze standaard ook voor elk lid van het type.
Deze overgenomen garantie kan worden overschreven door de ComponentGuaranteesAttribute toe te passen op afzonderlijke typen en typeleden. Echter, garanties die de standaardinstelling overschrijven, kunnen de garantie alleen verzwakken; ze kunnen deze niet versterken. Als een assembly bijvoorbeeld is gemarkeerd met de None garantie, hebben de typen en leden ervan geen compatibiliteitsgarantie en andere garanties die worden toegepast op typen of leden in de assembly, worden genegeerd.
De garantie testen
De Guarantees eigenschap retourneert een lid van de ComponentGuaranteesOptions opsomming, die is gemarkeerd met het FlagsAttribute kenmerk. Dit betekent dat u moet testen op de vlag waarin u geïnteresseerd bent door mogelijk onbekende vlaggen te maskeren. In het volgende voorbeeld wordt bijvoorbeeld getest of een type is gemarkeerd als 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
In het volgende voorbeeld wordt getest of een type is gemarkeerd als Stable of 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
In het volgende voorbeeld wordt getest of een type is gemarkeerd als None (dat wil zeggen, noch Stable noch 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