Classe System.Runtime.Versioning.ComponentGuaranteesAttribute

Cet article vous offre des remarques complémentaires à la documentation de référence pour cette API.

Il ComponentGuaranteesAttribute est utilisé par les développeurs de composants et de bibliothèques de classes pour indiquer le niveau de compatibilité que les consommateurs de leurs bibliothèques peuvent attendre entre plusieurs versions. Il indique le niveau de garantie qu’une version future de la bibliothèque ou du composant ne brisera pas un client existant. Les clients peuvent ensuite utiliser la ComponentGuaranteesAttribute méthode comme aide à la conception de leurs propres interfaces pour garantir la stabilité entre les versions.

Remarque

Le Common Language Runtime (CLR) n’utilise pas cet attribut de quelque manière que ce soit. Sa valeur consiste à documenter formellement l’intention de l’auteur du composant. Les outils au moment de la compilation peuvent également utiliser ces déclarations pour détecter les erreurs au moment de la compilation qui cassaient autrement la garantie déclarée.

Niveaux de compatibilité

Les ComponentGuaranteesAttribute niveaux de compatibilité suivants sont pris en charge par les membres de l’énumération ComponentGuaranteesOptions :

  • Aucune compatibilité de version à version (ComponentGuaranteesOptions.None). Le client peut s’attendre à ce que les futures versions interrompent le client existant. Pour plus d’informations, consultez la section Aucune compatibilité plus loin dans cet article.

  • Compatibilité de version à version côte à côte (ComponentGuaranteesOptions.SideBySide). Le composant a été testé pour fonctionner lorsque plusieurs versions de l’assembly sont chargées dans le même domaine d’application. En général, les futures versions peuvent interrompre la compatibilité. Toutefois, lorsque des modifications cassants sont apportées, l’ancienne version n’est pas modifiée, mais existe en même temps que la nouvelle version. L’exécution côte à côte est la méthode attendue pour que les clients existants fonctionnent lorsque des modifications cassants sont apportées. Pour plus d’informations, consultez la section de compatibilité côte à côte plus loin dans cet article.

  • Compatibilité de version à version stable (ComponentGuaranteesOptions.Stable). Les versions futures ne doivent pas interrompre le client et l’exécution côte à côte ne doit pas être nécessaire. Toutefois, si le client est rompu par inadvertance, il peut être possible d’utiliser l’exécution côte à côte pour résoudre le problème. Pour plus d’informations, consultez la section Compatibilité stable .

  • Compatibilité de version à version Exchange (ComponentGuaranteesOptions.Exchange). Des précautions extraordinaires sont prises pour s’assurer que les futures versions ne briseront pas le client. Le client doit utiliser uniquement ces types dans la signature des interfaces utilisées pour la communication avec d’autres assemblys déployés indépendamment les uns des autres. Une seule version de ces types est censée se trouver dans un domaine d’application donné, ce qui signifie que si un client s’interrompt, l’exécution côte à côte ne peut pas résoudre le problème de compatibilité. Pour plus d’informations, consultez la section de compatibilité des types Exchange.

Les sections suivantes décrivent plus en détail chaque niveau de garantie.

Aucune compatibilité

Marquer un composant comme ComponentGuaranteesOptions.None indique que le fournisseur ne garantit pas la compatibilité. Les clients doivent éviter de prendre des dépendances sur les interfaces exposées. Ce niveau de compatibilité est utile pour les types qui sont expérimentaux ou qui sont exposés publiquement, mais qui sont destinés uniquement aux composants qui sont toujours mis à jour en même temps. None indique explicitement que ce composant ne doit pas être utilisé par des composants externes.

Compatibilité côte à côte

Marquer un composant comme ComponentGuaranteesOptions.SideBySide indique que le composant a été testé pour fonctionner lorsque plusieurs versions de l’assembly sont chargées dans le même domaine d’application. Les modifications cassants sont autorisées tant qu’elles sont apportées à l’assembly dont le numéro de version est supérieur. Les composants liés à une ancienne version de l’assembly sont censés continuer à se lier à l’ancienne version, et d’autres composants peuvent être liés à la nouvelle version. Il est également possible de mettre à jour un composant déclaré en SideBySide modifiant de manière destructrice l’ancienne version.

Compatibilité stable

Marquer un type comme ComponentGuaranteesOptions.Stable indique que le type doit rester stable entre les versions. Toutefois, il peut également être possible pour les versions côte à côte d’un type stable d’exister dans le même domaine d’application.

Les types stables gèrent une barre de compatibilité binaire élevée. En raison de cela, les fournisseurs doivent éviter d’apporter des modifications cassants aux types stables. Les types de modifications suivants sont acceptables :

  • Ajout de champs d’instance privée à un type ou suppression de champs, tant que cela n’interrompt pas le format de sérialisation.
  • Modification d’un type non sérialisable en type sérialisable. (Toutefois, un type sérialisable ne peut pas être remplacé par un type non sérialisable.)
  • Lever de nouvelles exceptions dérivées d’une méthode.
  • Amélioration des performances d’une méthode.
  • Modification de la plage de valeurs de retour, tant que la modification n’affecte pas la majorité des clients.
  • Résolution de bogues graves, si la justification de l’entreprise est élevée et que le nombre de clients affectés négativement est faible.

Étant donné que les nouvelles versions des composants stables ne sont pas censées interrompre les clients existants, généralement une seule version d’un composant stable est nécessaire dans un domaine d’application. Toutefois, ce n’est pas une exigence, car les types stables ne sont pas utilisés en tant que types d’échange connus auxquels tous les composants sont d’accord. Par conséquent, si une nouvelle version d’un composant stable interrompt par inadvertance un composant et si d’autres composants ont besoin de la nouvelle version, il peut être possible de résoudre le problème en chargeant à la fois l’ancien et le nouveau composant.

Stable fournit une garantie de compatibilité de version plus forte que None. Il s’agit d’une valeur par défaut courante pour les composants multiversion.

Stable peut être combiné avec SideBySide, qui indique que le composant n’interrompt pas la compatibilité, mais est testé pour fonctionner lorsque plusieurs versions sont chargées dans un domaine d’application donné.

Une fois qu’un type ou une méthode est marqué comme Stable, il peut être mis à niveau vers Exchange. Toutefois, il ne peut pas être rétrogradé à None.

Compatibilité des types Exchange

Le marquage d’un type comme ComponentGuaranteesOptions.Exchange offre une garantie de compatibilité de version plus forte que Stable, et doit être appliqué à la plus stable de tous les types. Ces types sont destinés à être utilisés pour l’échange entre des composants générés indépendamment à travers toutes les limites des composants dans les deux temps (toute version du CLR ou toute version d’un composant ou d’une application) et de l’espace (interprocesseur, cross-CLR dans un processus, domaine inter-applications dans un CLR). Si une modification cassant est apportée à un type d’échange, il est impossible de résoudre le problème en chargeant plusieurs versions du type.

Les types Exchange doivent être modifiés uniquement lorsqu’un problème est très grave (par exemple, un problème de sécurité grave) ou que la probabilité de rupture est très faible (autrement dit, si le comportement a déjà été rompu de manière aléatoire sur laquelle le code n’a pas pu concevoir une dépendance). Vous pouvez apporter les types de modifications suivants à un type d’échange :

  • Ajoutez l’héritage des nouvelles définitions d’interface.

  • Ajoutez de nouvelles méthodes privées qui implémentent les méthodes des définitions d’interface nouvellement héritées.

  • Ajoutez de nouveaux champs statiques.

  • Ajoutez de nouvelles méthodes statiques.

  • Ajoutez de nouvelles méthodes d’instance non virtuelle.

Les éléments suivants sont considérés comme des changements cassants et ne sont pas autorisés pour les types primitifs :

  • Modification des formats de sérialisation. La sérialisation à tolérance de version est requise.

  • Ajout ou suppression de champs d’instance privée. Cela risque de modifier le format de sérialisation du type et du code client cassant qui utilise la réflexion.

  • Modification de la sérialisabilité d’un type. Un type non sérialisable peut ne pas être sérialisable, et inversement.

  • Levée d’exceptions différentes d’une méthode.

  • La modification de la plage des valeurs de retour d’une méthode, sauf si la définition de membre déclenche cette possibilité et indique clairement comment les clients doivent gérer des valeurs inconnues.

  • Résolution de la plupart des bogues. Les consommateurs du type s’appuient sur le comportement existant.

Une fois qu’un composant, un type ou un membre est marqué avec la Exchange garantie, il ne peut pas être modifié en tant que Stable composant ou None.

En règle générale, les types d’échange sont les types de base (tels que Int32 et String dans .NET) et les interfaces (telles que IList<T>, IEnumerable<T>et IComparable<T>) couramment utilisés dans les interfaces publiques.

Les types Exchange peuvent exposer publiquement uniquement d’autres types qui sont également marqués avec Exchange compatibilité. En outre, les types d’échange ne peuvent pas dépendre du comportement des API Windows susceptibles de changer.

Garanties de composant

Le tableau suivant indique comment les caractéristiques et l’utilisation d’un composant affectent sa garantie de compatibilité.

Caractéristiques des composants Exchange Stable Côte à côte Aucun
Peut être utilisé dans les interfaces entre les composants qui version indépendamment. O N N N
Peut être utilisé (en privé) par un assembly qui versions indépendamment. O O Y N
Peut avoir plusieurs versions dans un domaine d’application unique. N O O O
Peut apporter des modifications cassants N N O O
Testé pour que certaines versions de l’assembly puissent être chargées ensemble. N N Y N
Peut apporter des changements cassants en place. N N N O
Peut apporter des modifications de maintenance non cassants très sécurisées en place. O O O O

Appliquer l’attribut

Vous pouvez appliquer l’assembly ComponentGuaranteesAttribute , un type ou un membre de type. Son application est hiérarchique. Autrement dit, par défaut, la garantie définie par la Guarantees propriété de l’attribut au niveau de l’assembly définit la garantie de tous les types de l’assembly et de tous les membres de ces types. De même, si la garantie est appliquée au type, par défaut, elle s’applique également à chaque membre du type.

Cette garantie héritée peut être substituée en appliquant les ComponentGuaranteesAttribute types individuels et les membres de type. Toutefois, les garanties qui remplacent la valeur par défaut ne peuvent affaiblir que la garantie ; ils ne peuvent pas le renforcer. Par exemple, si un assembly est marqué avec la None garantie, ses types et ses membres n’ont aucune garantie de compatibilité, et toute autre garantie appliquée aux types ou aux membres de l’assembly est ignorée.

Tester la garantie

La Guarantees propriété retourne un membre de l’énumération ComponentGuaranteesOptions , qui est marquée avec l’attribut FlagsAttribute . Cela signifie que vous devez tester l’indicateur qui vous intéresse en masquant les indicateurs potentiellement inconnus. Par exemple, l’exemple suivant teste si un type est marqué comme Stable.

// Test whether guarantee is Stable.
if ((guarantee & ComponentGuaranteesOptions.Stable) == ComponentGuaranteesOptions.Stable)
   Console.WriteLine("{0} is marked as {1}.", typ.Name, 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

L’exemple suivant teste si un type est marqué comme Stable ou Exchange.

// Test whether guarantee is Stable or Exchange.
if ((guarantee & (ComponentGuaranteesOptions.Stable | ComponentGuaranteesOptions.Exchange)) > 0)
   Console.WriteLine("{0} is marked as Stable or Exchange.", typ.Name, guarantee);
' 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

L’exemple suivant teste un type avec un type est marqué comme None (autrement dit, ni Stable ).Exchange

// Test whether there is no guarantee (neither Stable nor Exchange).
if ((guarantee & (ComponentGuaranteesOptions.Stable | ComponentGuaranteesOptions.Exchange)) == 0)
   Console.WriteLine("{0} has no compatibility guarantee.", typ.Name, 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