Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Dieser Artikel enthält ergänzende Hinweise zur Referenzdokumentation für diese API.
Mit der AppContext Klasse können Bibliotheksautoren einen einheitlichen Opt-Out-Mechanismus für neue Funktionen für ihre Benutzer bereitstellen. Sie richtet einen lose gekoppelten Vertrag zwischen Komponenten ein, um eine Opt-Out-Anforderung zu kommunizieren. Diese Funktion ist in der Regel wichtig, wenn eine Änderung an vorhandenen Funktionen vorgenommen wird. Umgekehrt gibt es bereits ein implizites Opt-In für neue Funktionen.
AppContext für Bibliotheksentwickler
Bibliotheken verwenden die AppContext Klasse zum Definieren und Verfügbarmachen von Kompatibilitätsschaltern, während Bibliotheksbenutzer diese Schalter festlegen können, um das Bibliotheksverhalten zu beeinflussen. Standardmäßig stellen Bibliotheken die neue Funktionalität bereit, und sie ändern sie nur (d. h., sie stellen die vorherige Funktionalität bereit), wenn der Switch festgelegt ist. Dadurch können Bibliotheken ein neues Verhalten für eine vorhandene API bereitstellen und gleichzeitig Aufrufer unterstützen, die vom vorherigen Verhalten abhängig sind.
Definieren des Switchnamens
Die am häufigsten verwendete Möglichkeit, Verbrauchern Ihrer Bibliothek das Deaktivieren einer Verhaltensänderung zu ermöglichen, besteht darin, einen benannten Schalter zu definieren. Das value Element ist ein Name/Wert-Paar, das aus dem Namen eines Schalters und dessen Boolean Wert besteht. Standardmäßig ist der Schalter immer implizit false, der das neue Verhalten ermöglicht (und es standardmäßig aktiviert). Wenn Sie den Schalter auf true festlegen, wird er aktiviert, was das veraltete Verhalten zur Folge hat. Das explizite Festlegen des Schalters auf false führt ebenfalls zu dem neuen Verhalten.
Es ist vorteilhaft, ein einheitliches Format für Switchnamen zu verwenden, da sie ein formaler Vertrag sind, der von einer Bibliothek verfügbar gemacht wird. Es folgen zwei offensichtliche Formate:
- Wechseln. namespace. switchname
- Wechseln. bibliothek. switchname
Nachdem Sie den Switch definiert und dokumentiert haben, können Aufrufer ihn durch programmgesteuertes Aufrufen der AppContext.SetSwitch(String, Boolean) Methode verwenden. .NET Framework-Apps können den Switch auch verwenden, indem sie ihrer Anwendungskonfigurationsdatei oder mithilfe der Registrierung ein <AppContextSwitchOverrides> Element hinzufügen. Weitere Informationen dazu, wie Anrufer den Wert von AppContext Konfigurationsschaltern verwenden und festlegen, finden Sie im Abschnitt "AppContext für Bibliothekskunden".
Wenn die Common Language Runtime eine Anwendung ausführt, liest sie in .NET Framework automatisch die Kompatibilitätseinstellungen der Registrierung und lädt die Anwendungskonfigurationsdatei AppContext , um die Instanz der Anwendung aufzufüllen. Da die AppContext Instanz entweder programmgesteuert vom Aufrufer oder von der Laufzeit aufgefüllt wird, müssen .NET Framework-Apps keine Aktion ausführen, z. B. das Aufrufen der SetSwitch Methode, um die AppContext Instanz zu konfigurieren.
Überprüfen der Einstellung
Sie können überprüfen, ob ein Verbraucher den Wert des Schalters deklariert und entsprechend reagiert hat, indem Sie die AppContext.TryGetSwitch Methode aufrufen. Die Methode gibt zurück true , wenn das switchName Argument gefunden wird, und das isEnabled Argument gibt den Wert des Schalters an. Andernfalls gibt die Methode zurück false.
Beispiel
Im folgenden Beispiel wird gezeigt, wie die AppContext-Klasse dem Kunden ermöglicht, das ursprüngliche Verhalten einer Bibliotheksmethode festzulegen. Die folgende Version ist Version 1.0 einer Bibliothek mit dem Namen StringLibrary. Sie definiert eine SubstringStartsAt Methode, die einen Ordinalvergleich durchführt, um den Anfangsindex einer Teilzeichenfolge innerhalb einer größeren Zeichenfolge zu bestimmen.
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
Im folgenden Beispiel wird dann die Bibliothek verwendet, um den Anfangsindex der Teilzeichenfolge "archæ" in "The archaeologist" zu finden. Da die Methode einen Ordinalvergleich durchführt, kann die Teilzeichenfolge nicht gefunden werden.
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($"'{substring}' found in '{value}' starting at position {position}");
else
Console.WriteLine($"'{substring}' not found in '{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'
Version 2.0 der Bibliothek ändert jedoch die SubstringStartsAt Methode, um kultursensitiven Vergleich zu verwenden.
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
Wenn die App für die neue Version der Bibliothek neu kompiliert wird, meldet sie nun, dass die Unterzeichenfolge "archæ" an Index 4 in "The archaeologist" gefunden wird.
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($"'{substring}' found in '{value}' starting at position {position}");
else
Console.WriteLine($"'{substring}' not found in '{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
Diese Änderung kann daran gehindert werden, die Anwendungen zu unterbrechen, die vom ursprünglichen Verhalten abhängig sind, indem sie einen Schalter definieren. In diesem Fall wird der Schalter benannt StringLibrary.DoNotUseCultureSensitiveComparison. Der Standardwert gibt an, falsedass die Bibliothek einen kulturabhängigen Vergleich der Version 2.0 durchführen soll.
true gibt an, dass die Bibliothek einen ordinalen Vergleich der Version 1.0 durchführen soll. Eine geringfügige Änderung des vorherigen Codes ermöglicht es dem Bibliotheksanwender, den Schalter festzulegen, um die Art des Vergleichs zu bestimmen, den die Methode ausführt.
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
Eine .NET Framework-Anwendung kann dann die folgende Konfigurationsdatei verwenden, um das Verhalten der Version 1.0 wiederherzustellen.
<configuration>
<runtime>
<AppContextSwitchOverrides value="StringLibrary.DoNotUseCultureSensitiveComparison=true" />
</runtime>
</configuration>
Wenn die Anwendung mit der vorhandenen Konfigurationsdatei ausgeführt wird, erzeugt sie die folgende Ausgabe:
'archæ' not found in 'The archaeologist'
AppContext für Bibliothekskunden
Wenn Sie der Consumer einer Bibliothek sind, können Sie mit der AppContext Klasse den Opt-Out-Mechanismus einer Bibliothek oder Bibliotheksmethode für neue Funktionen nutzen. Einzelne Methoden der Klassenbibliothek, die Sie aufrufen, definieren bestimmte Schalter, die ein neues Verhalten aktivieren oder deaktivieren. Der Wert des Schalters ist ein Boolescher Wert. Wenn es falseist, was typischerweise der Standardwert ist, wird das neue Verhalten aktiviert; wenn es trueist, wird das neue Verhalten deaktiviert, und das Mitglied verhält sich wie zuvor.
Sie können den Wert einer Option festlegen, indem Sie die AppContext.SetSwitch(String, Boolean) Methode in Ihrem Code aufrufen. Das switchName Argument definiert den Switchnamen, und die isEnabled Eigenschaft definiert den Wert des Schalters. Da AppContext es sich um eine statische Klasse handelt, ist sie auf Anwendungsdomänenbasis verfügbar. Das Aufrufen des AppContext.SetSwitch(String, Boolean) hat einen Anwendungsbereich, das heißt, es wirkt sich nur auf die Anwendung aus.
.NET Framework-Apps haben zusätzliche Möglichkeiten zum Festlegen des Werts einer Option:
Durch Hinzufügen eines
<AppContextSwitchOverrides>Elements zum<runtime>Abschnitt der app.config Datei. Der Schalter verfügt über ein einzelnes Attribut,value, dessen Wert eine Zeichenfolge ist, die ein Schlüssel-Wert-Paar darstellt, das sowohl den Schalternamen als auch den Wert enthält.Um mehrere Schalter zu definieren, trennen Sie das Schlüssel-Wert-Paar jedes Schalters im
<AppContextSwitchOverrides>Attribut desvalueElements durch ein Semikolon. In diesem Fall weist das<AppContextSwitchOverrides>Element das folgende Format auf:<AppContextSwitchOverrides value="switchName1=value1;switchName2=value2" />Das Verwenden des
<AppContextSwitchOverrides>Elements zum Definieren einer Konfigurationseinstellung weist den Anwendungsbereich auf. Das heißt, es wirkt sich nur auf die Anwendung aus.Hinweis
Informationen zu den durch .NET Framework definierten Switches finden Sie unter
<AppContextSwitchOverrides>Element.Durch Hinzufügen eines Eintrags zur Registrierung. Fügen Sie dem Unterschlüssel HKLM\SOFTWARE\Microsoft\.NETFramework\AppContext einen neuen Zeichenfolgenwert hinzu. Legen Sie den Namen des Eintrags auf den Namen des Switches fest. Legen Sie den Wert auf eine der folgenden Optionen fest:
True, , ,true,Falseoderfalse. Wenn die Laufzeit auf einen anderen Wert trifft, wird der Schalter ignoriert.Auf einem 64-Bit-Betriebssystem müssen Sie auch denselben Eintrag zum HKLM\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\AppContext-Unterschlüssel hinzufügen.
Die Verwendung der Registrierung zum Definieren eines AppContext Switchs weist einen Computerbereich auf. Das heißt, es wirkt sich auf jede Anwendung aus, die auf dem Computer ausgeführt wird.
Für ASP.NET und ASP.NET Core-Anwendungen legen Sie einen Schalter fest, indem Sie dem <Add> Abschnitt der web.config Datei ein <appSettings> Element hinzufügen. Beispiel:
<appSettings>
<add key="AppContext.SetSwitch:switchName1" value="switchValue1" />
<add key="AppContext.SetSwitch:switchName2" value="switchValue2" />
</appSettings>
Wenn Sie denselben Schalter auf mehr als eine Weise einstellen, ist die Reihenfolge, welche Einstellung die anderen überschreibt, wie folgt:
- Die programmgesteuerte Einstellung.
- Die Einstellung in der app.config-Datei (für .NET Framework-Apps) oder der web.config-Datei (für ASP.NET Core-Apps).
- Die Registrierungseinstellung (nur für .NET Framework-Apps).