AppContext Класс

Определение

Предоставляет элементы для настройки и получения данных о контексте приложения.

public ref class AppContext abstract sealed
public static class AppContext
type AppContext = class
Public Class AppContext
Наследование
AppContext

Комментарии

Класс AppContext позволяет разработчикам библиотек предоставлять унифицированный механизм отключения новой функциональности для своих пользователей. Он устанавливает слабо связанный контракт между компонентами, чтобы сообщить запрос на отказ. Эта возможность обычно важна при изменении существующих функциональных возможностей. И наоборот, уже существует неявное согласие на новые функциональные возможности.

AppContext для разработчиков библиотек

Библиотеки используют класс AppContext для определения и предоставления коммутаторов совместимости, в то время как пользователи библиотеки могут задать эти параметры, чтобы повлиять на поведение библиотеки. По умолчанию библиотеки предоставляют новые функциональные возможности, и изменяют их на прежние, только если установлен соответствующий параметр. Это позволяет библиотекам предоставлять новое поведение для существующего API, продолжая поддерживать тех, кто зависит от предыдущего поведения.

Определение имени переключателя

Наиболее распространенный способ разрешить потребителям библиотеки отказаться от изменения поведения — определить именованный коммутатор. Его элемент value — это пара name/value, состоящая из имени коммутатора и его Boolean значения. По умолчанию параметр всегда неявно false, который обеспечивает и активирует новое поведение. Установка переключателя на true активирует его, что возвращает устаревшее поведение. Явная установка переключателя на false также обеспечивает новое поведение.

Полезно использовать единообразный формат имен для переключателей, поскольку они являются частью формального контракта, представленного библиотекой. Ниже приведены два очевидных формата:

  • Switch.пространства имен.switchname
  • коммутатор.библиотека.имя коммутатора

После определения и документирования коммутатора пользователи могут использовать его, программно вызывая метод AppContext.SetSwitch(String, Boolean).

Проверка параметра

Можно определить, сообщил ли пользователь значение переключателя, и при необходимости действовать, вызвав метод AppContext.TryGetSwitch. Метод возвращает true, если найден аргумент switchName, а его аргумент isEnabled указывает значение коммутатора. В противном случае метод возвращает false.

Пример

В следующем примере показано использование класса AppContext, позволяющего клиенту выбрать исходное поведение метода библиотеки. Ниже приведена версия 1.0 библиотеки с именем StringLibrary. Он определяет метод SubstringStartsAt, который выполняет порядковое сравнение, чтобы определить начальный индекс подстроки в более крупной строке.

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

В следующем примере библиотека используется для поиска начального индекса подстроки "архе" в "Археолог". Так как метод выполняет порядковое сравнение, подстрока не найдена.

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'

Однако версия 2.0 библиотеки изменяет метод SubstringStartsAt для использования сравнения с учетом языка и региональных параметров.

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

Когда приложение перекомпилируется для запуска с новой версией библиотеки, оно теперь сообщает, что подстрока "archæ" найдена на индексе 4 в "The archaeologist".

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

Это изменение может быть предотвращено, чтобы не нарушать работу приложений, зависящих от исходного поведения, за счет использования переключателя. В этом случае переключатель называется StringLibrary.DoNotUseCultureSensitiveComparison. Значение по умолчанию, false, указывает, что библиотека должна выполнять сравнение с учетом культурных различий версии 2.0. true указывает, что библиотека должна выполнять её порядковое сравнение для версии 1.0. Небольшое изменение предыдущего кода позволяет потребителю библиотеки задать параметр для определения типа сравнения, выполняемого методом.

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 для потребителей библиотеки

Если вы являетесь потребителем библиотеки, класс AppContext позволяет воспользоваться опцией отключения новых функций библиотеки или метода библиотеки. Отдельные методы вызываемой библиотеки классов определяют определенные коммутаторы, которые позволяют включить или отключить новое поведение. Значение переключателя является логическим. Если это false, которое обычно является значением по умолчанию, новое поведение включено; Если это true, новое поведение отключено, и член ведет себя так, как это было ранее.

Можно задать значение коммутатора, вызвав метод AppContext.SetSwitch(String, Boolean) в коде. Аргумент switchName определяет имя коммутатора, а свойство isEnabled определяет значение коммутатора. Так как AppContext является статическим классом, он доступен на основе домена для каждого приложения. Вызов AppContext.SetSwitch(String, Boolean) имеет область приложения; то есть это влияет только на приложение.

Для приложений ASP.NET Core установите переключатель, добавив элемент <Add> в раздел <appSettings> файла web.config. Рассмотрим пример.

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

Если один и тот же переключатель задан несколькими способами, порядок приоритета для определения того, какой из них имеет приоритет над другими:

  1. Программная настройка.
  2. Параметр в файле web.config (для приложений ASP.NET Core).

Свойства

Имя Описание
BaseDirectory

Возвращает путь к файлу базового каталога, который сопоставитель сборок использует для проверки сборок.

TargetFrameworkName

Возвращает имя версии платформы, предназначенной для текущего приложения.

Методы

Имя Описание
GetData(String)

Возвращает значение именованного элемента данных, назначенного текущему домену приложения.

SetData(String, Object)

Задает значение именованного элемента данных, назначенного текущему домену приложения.

SetSwitch(String, Boolean)

Задает значение коммутатора.

TryGetSwitch(String, Boolean)

Пытается получить значение коммутатора.

Применяется к