Partager via


Classe System.AppContext

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

La AppContext classe permet aux enregistreurs de bibliothèque de fournir un mécanisme d’annulation uniforme pour de nouvelles fonctionnalités pour leurs utilisateurs. Elle établit un contrat souple entre les composants pour la communication des demandes de désactivation. Cette fonctionnalité est particulièrement importante quand une modification est apportée aux fonctionnalités existantes. À l'inverse, il existe déjà une activation implicite des nouvelles fonctionnalités.

AppContext pour les développeurs de bibliothèques

Les bibliothèques utilisent la AppContext classe pour définir et exposer des commutateurs de compatibilité, tandis que les utilisateurs de la bibliothèque peuvent définir ces commutateurs pour affecter le comportement de la bibliothèque. Par défaut, les bibliothèques fournissent la nouvelle fonctionnalité et ne peuvent la modifier (c'est-à-dire fournir la version antérieure) que si le commutateur est défini. Cela permet aux bibliothèques de fournir un nouveau comportement pour une API existante tout en continuant à prendre en charge les appelants qui dépendent du comportement précédent.

Définir le nom du commutateur

La façon la plus courante de permettre aux consommateurs de votre bibliothèque de refuser un changement de comportement consiste à définir un commutateur nommé. Son value élément est une paire nom/valeur qui se compose du nom d’un commutateur et de sa Boolean valeur. Par défaut, le commutateur est toujours implicitement false, qui fournit le nouveau comportement (et rend le nouveau comportement opt-in par défaut). Définition du commutateur pour true l’activer, qui fournit le comportement hérité. Définir explicitement le commutateur pour false fournir également le nouveau comportement.

Il est utile d’utiliser un format cohérent pour les noms de commutateurs, car ils sont un contrat formel exposé par une bibliothèque. Voici deux formats évidents :

  • Commutateur.espace de noms.nom_commutateur
  • Commutateur.bibliothèque.nom_commutateur

Une fois que vous avez défini et documenté le commutateur, les appelants peuvent l’utiliser en appelant la AppContext.SetSwitch(String, Boolean) méthode par programmation. Les applications .NET Framework peuvent également utiliser le commutateur en ajoutant un <élément AppContextSwitchOverrides> à leur fichier de configuration d’application ou à l’aide du Registre. Pour plus d’informations sur la façon dont les appelants utilisent et définissent la valeur des commutateurs de AppContext configuration, consultez la section AppContext pour les consommateurs de bibliothèque.

Dans .NET Framework, lorsque le Common Language Runtime exécute une application, il lit automatiquement les paramètres de compatibilité du Registre et charge le fichier de configuration de l’application pour remplir l’instance de l’application AppContext . Étant donné que l’instance AppContext est remplie par programme par l’appelant ou par le runtime, les applications .NET Framework n’ont pas besoin d’effectuer d’action, comme appeler la SetSwitch méthode, pour configurer l’instance AppContext .

Vérifier le paramètre

Vous pouvez case activée si un consommateur a déclaré la valeur du commutateur et agir correctement en appelant la AppContext.TryGetSwitch méthode. La méthode retourne true si l’argument switchName est trouvé et son isEnabled argument indique la valeur du commutateur. Dans le cas contraire, la méthode retourne false.

Exemple

L’exemple suivant illustre l’utilisation de la AppContext classe pour permettre au client de choisir le comportement d’origine d’une méthode de bibliothèque. Voici la version 1.0 d’une bibliothèque nommée StringLibrary. Il définit une méthode qui effectue une SubstringStartsAt comparaison ordinale pour déterminer l’index de départ d’une sous-chaîne dans une chaîne plus grande.

using System;
using System.Reflection;

[assembly: AssemblyVersion("1.0.0.0")]

public static class StringLibrary1
{
    public static int SubstringStartsAt(string fullString, string substr)
    {
        return fullString.IndexOf(substr, StringComparison.Ordinal);
    }
}
open System
open System.Reflection

[<assembly: AssemblyVersion("1.0.0.0")>]
do ()

module StringLibrary =
    let substringStartsAt (fullString: string) (substr: string) =
        fullString.IndexOf(substr, StringComparison.Ordinal)
Imports System.Reflection

<Assembly: AssemblyVersion("1.0.0.0")>

Public Class StringLibrary
   Public Shared Function SubstringStartsAt(fullString As String, substr As String) As Integer
      Return fullString.IndexOf(substr, StringComparison.Ordinal)
   End Function
End Class

L’exemple suivant utilise ensuite la bibliothèque pour trouver l’index de départ de la sous-chaîne « archæ » dans « L’archéologue ». Étant donné que la méthode effectue une comparaison ordinale, la sous-chaîne est introuvable.

using System;

public class Example1
{
    public static void Main()
    {
        string value = "The archaeologist";
        string substring = "archæ";
        int position = StringLibrary1.SubstringStartsAt(value, substring);
        if (position >= 0)
            Console.WriteLine("'{0}' found in '{1}' starting at position {2}",
                           substring, value, position);
        else
            Console.WriteLine("'{0}' not found in '{1}'", substring, value);
    }
}
// The example displays the following output:
//       'archæ' not found in 'The archaeologist'
let value = "The archaeologist"
let substring = "archæ"

let position =
    StringLibrary.substringStartsAt value substring

if position >= 0 then
    printfn $"'{substring}' found in '{value}' starting at position {position}"
else
    printfn $"'{substring}' not found in '{value}'"

// The example displays the following output:
//       'archæ' not found in 'The archaeologist'
Public Module Example4
    Public Sub Main()
        Dim value As String = "The archaeologist"
        Dim substring As String = "archæ"
        Dim position As Integer = StringLibrary.SubstringStartsAt(value, substring)
        If position >= 0 Then
            Console.WriteLine("'{0}' found in '{1}' starting at position {2}",
                        substring, value, position)
        Else
            Console.WriteLine("'{0}' not found in '{1}'", substring, value)
        End If
    End Sub
End Module
' The example displays the following output:
'       'archæ' not found in 'The archaeologist'

Toutefois, la version 2.0 de la bibliothèque modifie la méthode pour utiliser la comparaison sensible à la SubstringStartsAt culture.

using System;
using System.Reflection;

[assembly: AssemblyVersion("2.0.0.0")]

public static class StringLibrary2
{
    public static int SubstringStartsAt(string fullString, string substr)
    {
        return fullString.IndexOf(substr, StringComparison.CurrentCulture);
    }
}
open System
open System.Reflection

[<assembly: AssemblyVersion("2.0.0.0")>]
do ()

module StringLibrary =
    let substringStartsAt (fullString: string) (substr: string) =
        fullString.IndexOf(substr, StringComparison.CurrentCulture)
Imports System.Reflection

<Assembly: AssemblyVersion("2.0.0.0")>

Public Class StringLibrary
   Public Shared Function SubstringStartsAt(fullString As String, substr As String) As Integer
      Return fullString.IndexOf(substr, StringComparison.CurrentCulture)
   End Function
End Class

Lorsque l’application est recompilée pour s’exécuter sur la nouvelle version de la bibliothèque, elle signale maintenant que la sous-chaîne « archæ » est trouvée à l’index 4 dans « L’archéologue ».

using System;

public class Example2
{
    public static void Main()
    {
        string value = "The archaeologist";
        string substring = "archæ";
        int position = StringLibrary2.SubstringStartsAt(value, substring);
        if (position >= 0)
            Console.WriteLine("'{0}' found in '{1}' starting at position {2}",
                           substring, value, position);
        else
            Console.WriteLine("'{0}' not found in '{1}'", substring, value);
    }
}
// The example displays the following output:
//       'archæ' found in 'The archaeologist' starting at position 4
let value = "The archaeologist"
let substring = "archæ"

let position =
    StringLibrary.substringStartsAt value substring

if position >= 0 then
    printfn $"'{substring}' found in '{value}' starting at position {position}"
else
    printfn $"'{substring}' not found in '{value}'"

// The example displays the following output:
//       'archæ' found in 'The archaeologist' starting at position 4
Public Module Example6
    Public Sub Main()
        Dim value As String = "The archaeologist"
        Dim substring As String = "archæ"
        Dim position As Integer = StringLibrary.SubstringStartsAt(value, substring)
        If position >= 0 Then
            Console.WriteLine("'{0}' found in '{1}' starting at position {2}",
                        substring, value, position)
        Else
            Console.WriteLine("'{0}' not found in '{1}'", substring, value)
        End If
    End Sub
End Module
' The example displays the following output:
'       'archæ' found in 'The archaeologist' starting at position 4

Cette modification peut être empêchée de briser les applications qui dépendent du comportement d’origine en définissant un commutateur. Dans ce cas, le commutateur est nommé StringLibrary.DoNotUseCultureSensitiveComparison. Sa valeur par défaut indique falseque la bibliothèque doit effectuer sa comparaison avec la culture version 2.0. true indique que la bibliothèque doit effectuer sa comparaison ordinale version 1.0. Une légère modification du code précédent permet au consommateur de bibliothèque de définir le commutateur pour déterminer le type de comparaison effectué par la méthode.

using System;
using System.Reflection;

[assembly: AssemblyVersion("2.0.0.0")]

public static class StringLibrary
{
   public static int SubstringStartsAt(string fullString, string substr)
   {
      bool flag;
      if (AppContext.TryGetSwitch("StringLibrary.DoNotUseCultureSensitiveComparison", out flag) && flag == true)
         return fullString.IndexOf(substr, StringComparison.Ordinal);
      else
         return fullString.IndexOf(substr, StringComparison.CurrentCulture);
   }
}
open System
open System.Reflection

[<assembly: AssemblyVersion("2.0.0.0")>]
do ()

AppContext.SetSwitch("StringLibrary.DoNotUseCultureSensitiveComparison",true)

module StringLibrary =
    let substringStartsAt (fullString: string) (substr: string) =
        match AppContext.TryGetSwitch "StringLibrary.DoNotUseCultureSensitiveComparison" with 
        | true, true -> fullString.IndexOf(substr, StringComparison.Ordinal)
        | _ -> fullString.IndexOf(substr, StringComparison.CurrentCulture)
Imports System.Reflection

<Assembly: AssemblyVersion("2.0.0.0")>

Public Class StringLibrary
   Public Shared Function SubstringStartsAt(fullString As String, substr As String) As Integer
      Dim flag As Boolean
      If AppContext.TryGetSwitch("StringLibrary.DoNotUseCultureSensitiveComparison", flag) AndAlso flag = True Then
         Return fullString.IndexOf(substr, StringComparison.Ordinal)
      Else
         Return fullString.IndexOf(substr, StringComparison.CurrentCulture)
      End If   
   End Function
End Class

Une application .NET Framework peut ensuite utiliser le fichier de configuration suivant pour restaurer le comportement de la version 1.0.

<configuration>
   <runtime>
      <AppContextSwitchOverrides value="StringLibrary.DoNotUseCultureSensitiveComparison=true" />
   </runtime>
</configuration>

Lorsque l’application est exécutée avec le fichier de configuration présent, elle produit la sortie suivante :

'archæ' not found in 'The archaeologist'

AppContext pour les consommateurs de bibliothèque

Si vous êtes le consommateur d’une bibliothèque, la AppContext classe vous permet de tirer parti du mécanisme d’annulation d’une méthode de bibliothèque ou de bibliothèque pour de nouvelles fonctionnalités. Les méthodes individuelles de la bibliothèque de classes que vous appelez définissent des commutateurs particuliers qui activent ou désactivent un nouveau comportement. La valeur du commutateur est une valeur booléenne. S’il s’agit falsegénéralement de la valeur par défaut, le nouveau comportement est activé ; s’il truele fait, le nouveau comportement est désactivé et le membre se comporte comme il l’a fait précédemment.

Vous pouvez définir la valeur d’un commutateur en appelant la AppContext.SetSwitch(String, Boolean) méthode dans votre code. L’argument switchName définit le nom du commutateur et la isEnabled propriété définit la valeur du commutateur. Étant donné qu’il AppContext s’agit d’une classe statique, elle est disponible par domaine d’application. L’appel de l’application AppContext.SetSwitch(String, Boolean) a une étendue d’application ; autrement dit, elle affecte uniquement l’application.

Les applications .NET Framework ont des moyens supplémentaires de définir la valeur d’un commutateur :

  • En ajoutant un <AppContextSwitchOverrides> élément à la <section runtime> du fichier app.config. Le commutateur a un attribut unique, valuedont la valeur est une chaîne qui représente une paire clé/valeur contenant à la fois le nom du commutateur et sa valeur.

    Pour définir plusieurs commutateurs, séparez la paire clé/valeur de chaque commutateur dans l’attribut de value l’élément <AppContextSwitchOverrides> avec un point-virgule. Dans ce cas, l’élément <AppContextSwitchOverrides> a le format suivant :

    <AppContextSwitchOverrides value="switchName1=value1;switchName2=value2" />
    

    L’utilisation de l’élément <AppContextSwitchOverrides> pour définir un paramètre de configuration a une étendue d’application ; autrement dit, elle affecte uniquement l’application.

    Remarque

    Pour plus d’informations sur les commutateurs définis par .NET Framework, consultez <l’élément AppContextSwitchOverrides>.

  • En ajoutant une entrée au Registre. Ajoutez une nouvelle valeur de chaîne à HKLM\SOFTWARE\Microsoft\. Sous-clé NETFramework\AppContext . Définissez le nom de l’entrée sur le nom du commutateur. Définissez sa valeur sur l’une des options suivantes : True, , true, Falseou false. Si le runtime rencontre une autre valeur, il ignore le commutateur.

    Sur un système d’exploitation 64 bits, vous devez également ajouter la même entrée à HKLM\SOFTWARE\Wow6432Node\Microsoft\. Sous-clé NETFramework\AppContext .

    L’utilisation du Registre pour définir un commutateur a une étendue d’ordinateur AppContext ; autrement dit, elle affecte chaque application s’exécutant sur l’ordinateur.

Pour les applications ASP.NET et ASP.NET Core, vous définissez un commutateur en ajoutant un élément Add> à l’application <Paramètres> section du fichier web.config.< Par exemple :

<appSettings>
   <add key="AppContext.SetSwitch:switchName1" value="switchValue1" />
   <add key="AppContext.SetSwitch:switchName2" value="switchValue2" />
</appSettings>

Si vous définissez le même commutateur de plusieurs façons, l’ordre de priorité pour déterminer quel paramètre remplace les autres est :

  1. Paramètre programmatique.
  2. Paramètre dans le fichier app.config (pour les applications .NET Framework) ou le fichier web.config (pour les applications ASP.NET Core).
  3. Paramètre de Registre (pour les applications .NET Framework uniquement).

Voir aussi