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 false
wartość .
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 false
to , czyli zazwyczaj wartość domyślna, nowe zachowanie jest włączone; jeśli jest true
to , 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 ,value
któ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
, ,true
False
lubfalse
. 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:
- Ustawienie programowe.
- Ustawienie w pliku app.config (dla aplikacji .NET Framework) lub pliku web.config (dla aplikacji ASP.NET Core).
- Ustawienie rejestru (tylko dla aplikacji .NET Framework).