System.AppContext, klasa

Ten artykuł zawiera dodatkowe uwagi dotyczące dokumentacji referencyjnej dla tego interfejsu API.

Klasa AppContext umożliwia autorom bibliotek zapewnienie jednolitego mechanizmu rezygnacji dla nowych funkcji dla użytkowników. Ustanawia luźno sprzężony kontrakt między składnikami w celu przekazania żądania rezygnacji. Ta funkcja jest zwykle ważna, gdy wprowadzono zmianę w istniejących funkcjach. Z drugiej strony istnieje już niejawna zgoda na nowe funkcje.

AppContext dla deweloperów bibliotek

Biblioteki używają AppContext klasy do definiowania i uwidaczniania przełączników zgodności, podczas gdy użytkownicy bibliotek mogą ustawić te przełączniki tak, aby wpływały na zachowanie biblioteki. Domyślnie biblioteki udostępniają nowe funkcje i zmieniają ją tylko (czyli udostępniają poprzednie funkcje), jeśli przełącznik jest ustawiony. Dzięki temu biblioteki mogą udostępniać nowe zachowanie dla istniejącego interfejsu API, a jednocześnie obsługiwać osoby wywołujące, które zależą od poprzedniego zachowania.

Definiowanie nazwy przełącznika

Najczęstszym sposobem zezwolenia użytkownikom biblioteki na rezygnację ze zmiany zachowania jest zdefiniowanie nazwanego przełącznika. Jego value element jest parą name/value, która składa się z nazwy przełącznika i jego Boolean wartości. Domyślnie przełącznik jest zawsze niejawnie false, co zapewnia nowe zachowanie (i sprawia, że nowe zachowanie jest domyślnie opt-in). Ustawienie przełącznika w celu true włączenia go, co zapewnia starsze zachowanie. Jawne ustawienie przełącznika w celu false zapewnia również nowe zachowanie.

Korzystne jest użycie spójnego formatu dla nazw przełączników, ponieważ są one formalnym kontraktem udostępnianym przez bibliotekę. Poniżej przedstawiono dwa oczywiste formaty:

  • Przełącznik.przestrzeń nazw.switchname
  • Przełącznik.biblioteka.switchname

Po zdefiniowaniu i udokumentowaniu przełącznika osoby wywołujące mogą jej używać przez programowe wywołanie AppContext.SetSwitch(String, Boolean) metody. Aplikacje .NET Framework mogą również używać przełącznika przez dodanie <elementu AppContextSwitchOverrides> do pliku konfiguracji aplikacji lub przy użyciu rejestru. Aby uzyskać więcej informacji na temat używania i ustawiania wartości AppContext przełączników konfiguracji, zobacz sekcję AppContext dla użytkowników biblioteki.

W programie .NET Framework, gdy środowisko uruchomieniowe języka wspólnego uruchamia aplikację, automatycznie odczytuje ustawienia zgodności rejestru i ładuje plik konfiguracji aplikacji w celu wypełnienia wystąpienia aplikacji AppContext . AppContext Ponieważ wystąpienie jest wypełniane programowo przez obiekt wywołujący lub środowisko uruchomieniowe, aplikacje programu .NET Framework nie muszą podejmować żadnych działań, takich jak wywoływanie SetSwitch metody, aby skonfigurować AppContext wystąpienie.

Sprawdzanie ustawienia

Możesz sprawdzić, czy użytkownik zadeklarował wartość przełącznika i działa odpowiednio, wywołując metodę AppContext.TryGetSwitch . Metoda zwraca true wartość, jeśli switchName argument zostanie znaleziony, a jego isEnabled argument wskazuje wartość przełącznika. W przeciwnym razie metoda zwraca falsewartość .

Przykład

Poniższy przykład ilustruje użycie AppContext klasy, aby umożliwić klientowi wybranie oryginalnego zachowania metody biblioteki. Poniżej znajduje się wersja 1.0 biblioteki o nazwie StringLibrary. Definiuje metodę SubstringStartsAt , która wykonuje porównanie porządkowe w celu określenia indeksu początkowego podciągów w większym ciągu.

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

Poniższy przykład używa następnie biblioteki do znalezienia indeksu początkowego podciągów "archæ" w "Archeologu". Ponieważ metoda wykonuje porównanie porządkowe, nie można odnaleźć podciągów.

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'

Jednak wersja 2.0 biblioteki zmienia metodę SubstringStartsAt tak, aby korzystała z porównania wrażliwego na kulturę.

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

Gdy aplikacja zostanie ponownie skompilowana do uruchomienia w nowej wersji biblioteki, teraz zgłasza, że podciąg "archæ" znajduje się na indeksie 4 w "Archeolog".

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

Tej zmiany można zapobiec przerwaniu działania aplikacji, które zależą od oryginalnego zachowania, definiując przełącznik. W tym przypadku przełącznik ma nazwę StringLibrary.DoNotUseCultureSensitiveComparison. Jego wartość domyślna, , wskazuje, falseże biblioteka powinna wykonać porównanie z uwzględnieniem kultury w wersji 2.0. true wskazuje, że biblioteka powinna wykonać porównanie porządkowe w wersji 1.0. Niewielka modyfikacja poprzedniego kodu umożliwia użytkownikowi biblioteki ustawienie przełącznika w celu określenia rodzaju porównania, które wykonuje metoda.

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

Aplikacja .NET Framework może następnie użyć następującego pliku konfiguracji, aby przywrócić zachowanie wersji 1.0.

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

Po uruchomieniu aplikacji z obecnym plikiem konfiguracji generuje następujące dane wyjściowe:

'archæ' not found in 'The archaeologist'

AppContext dla użytkowników biblioteki

Jeśli jesteś użytkownikiem biblioteki, AppContext klasa umożliwia korzystanie z mechanizmu rezygnacji z biblioteki lub biblioteki dla nowych funkcji. Poszczególne metody biblioteki klas, które wywołujesz, definiują określone przełączniki, które włączają lub wyłączają nowe zachowanie. Wartość przełącznika jest wartością logiczną. Jeśli jest falseto , czyli zazwyczaj wartość domyślna, nowe zachowanie jest włączone; jeśli jest trueto , nowe zachowanie jest wyłączone, a element członkowski zachowuje się tak jak poprzednio.

Wartość przełącznika można ustawić, wywołując metodę AppContext.SetSwitch(String, Boolean) w kodzie. Argument switchName definiuje nazwę przełącznika, a isEnabled właściwość definiuje wartość przełącznika. Ponieważ AppContext jest klasą statyczną, jest ona dostępna dla każdej domeny aplikacji. AppContext.SetSwitch(String, Boolean) Wywoływanie zakresu aplikacji, czyli wpływa tylko na aplikację.

Aplikacje .NET Framework mają dodatkowe sposoby ustawiania wartości przełącznika:

  • <AppContextSwitchOverrides> Dodając element do <sekcji środowiska uruchomieniowego> pliku app.config. Przełącznik ma jeden atrybut , valuektórego wartość jest ciągiem reprezentującym parę klucz/wartość zawierającą zarówno nazwę przełącznika, jak i jego wartość.

    Aby zdefiniować wiele przełączników, należy oddzielić parę klucz/wartość każdego przełącznika value w atrybucie< elementu AppContextSwitchOverrides> średnikiem. W takim przypadku <AppContextSwitchOverrides> element ma następujący format:

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

    <AppContextSwitchOverrides> Użycie elementu do zdefiniowania ustawienia konfiguracji ma zakres aplikacji, czyli wpływa tylko na aplikację.

    Uwaga

    Aby uzyskać informacje na temat przełączników zdefiniowanych przez program .NET Framework, zobacz Element AppContextSwitchOverrides>.<

  • Dodając wpis do rejestru. Dodaj nową wartość ciągu do HKLM\SOFTWARE\Microsoft\. PODklucz NETFramework\AppContext . Ustaw nazwę wpisu na nazwę przełącznika. Ustaw jego wartość na jedną z następujących opcji: True, , trueFalselub false. Jeśli środowisko uruchomieniowe napotka inną wartość, ignoruje przełącznik.

    W 64-bitowym systemie operacyjnym należy również dodać ten sam wpis do HKLM\SOFTWARE\Wow6432Node\Microsoft\. PODklucz NETFramework\AppContext .

    Definiowanie przełącznika AppContext przy użyciu rejestru ma zakres maszyny, co oznacza, że ma wpływ na każdą aplikację działającą na maszynie.

W przypadku aplikacji ASP.NET i ASP.NET Core należy ustawić przełącznik, dodając <element Add> do <aplikacji Ustawienia> sekcję pliku web.config. Na przykład:

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

Jeśli ustawisz ten sam przełącznik w więcej niż jeden sposób, kolejność pierwszeństwa podczas określania, które ustawienie zastępuje pozostałe, to:

  1. Ustawienie programowe.
  2. Ustawienie w pliku app.config (dla aplikacji .NET Framework) lub pliku web.config (dla aplikacji ASP.NET Core).
  3. Ustawienie rejestru (tylko dla aplikacji .NET Framework).

Zobacz też