AppContext Klasse

Definition

Stellt Member zum Festlegen und Abrufen von Daten über den Kontext einer Anwendung bereit.

public ref class AppContext abstract sealed
public static class AppContext
type AppContext = class
Public Class AppContext
Vererbung
AppContext

Hinweise

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 einen impliziten Opt-In-Mechanismus für neue Funktionalität.

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.

Ü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

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.

Für ASP.NET Core Anwendungen legen Sie einen Schalter fest, indem Sie dem Abschnitt <Add> 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:

  1. Die programmgesteuerte Einstellung.
  2. Die Einstellung in der datei web.config (für ASP.NET Core Apps).

Eigenschaften

Name Beschreibung
BaseDirectory

Ruft den Dateipfad des Basisverzeichnisses ab, das der Assemblylöser zum Untersuchen von Assemblys verwendet.

TargetFrameworkName

Ruft den Namen der Framework-Version ab, die von der aktuellen Anwendung gezielt ist.

Methoden

Name Beschreibung
GetData(String)

Gibt den Wert des benannten Datenelements zurück, das der aktuellen Anwendungsdomäne zugewiesen ist.

SetData(String, Object)

Legt den Wert des benannten Datenelements fest, das der aktuellen Anwendungsdomäne zugewiesen ist.

SetSwitch(String, Boolean)

Legt den Wert eines Schalters fest.

TryGetSwitch(String, Boolean)

Versucht, den Wert eines Schalters abzurufen.

Gilt für: