Класс System.AppContext
В этой статье приводятся дополнительные замечания к справочной документации по этому API.
Класс AppContext позволяет писателям библиотек предоставлять единый механизм отказа для новых функциональных возможностей для своих пользователей. Он устанавливает слабо связанный контракт между компонентами для передачи запроса на явный отказ. Эта возможность обычно важна при внесении изменений в существующие функции. В свою очередь, режим неявного согласия для новых функциональных возможностей уже существует.
AppContext для разработчиков библиотек
Библиотеки используют AppContext класс для определения и предоставления параметров совместимости, а пользователи библиотеки могут задать эти переключатели, чтобы повлиять на поведение библиотеки. По умолчанию библиотеки предоставляют новые функции и изменяют их (то есть предоставляют прежние функции) только в том случае, если установлен параметр. Это позволяет библиотекам предоставлять новое поведение для существующего API, продолжая поддерживать вызывающих лиц, которые зависят от предыдущего поведения.
Определение имени переключателя
Наиболее распространенный способ разрешить потребителям библиотеки отказаться от изменения поведения — определить именованный коммутатор. Его value
элемент — это пара name/value, состоящая из имени коммутатора и его Boolean значения. По умолчанию параметр всегда неявно false
, который обеспечивает новое поведение (и делает новое поведение по умолчанию). Если параметр включен true
, он обеспечивает устаревшее поведение. Явное задание переключателя false
также обеспечивает новое поведение.
Полезно использовать согласованный формат для имен переключения, так как он является формальным контрактом, предоставляемым библиотекой. Ниже приведены два очевидных формата:
- параметр. пространство_именимя_параметра
- параметр.библиотека.имя_параметра
После определения и документирования коммутатора вызывающие элементы могут использовать его, вызывая метод программным способом AppContext.SetSwitch(String, Boolean) . платформа .NET Framework приложения также могут использовать переключатель, добавив <Элемент AppContextSwitchOverrides> в файл конфигурации приложения или с помощью реестра. Дополнительные сведения о том, как вызывающие пользователи используют и задают значение AppContext коммутаторов конфигурации, см. в разделе AppContext для потребителей библиотеки.
В платформа .NET Framework, когда среда CLR запускает приложение, она автоматически считывает параметры совместимости реестра и загружает файл конфигурации приложения для заполнения экземпляра AppContext приложения. AppContext Так как экземпляр заполняется либо вызывающим оператором, либо средой выполнения, платформа .NET Framework приложения не должны предпринимать никаких действий, таких как вызов SetSwitch метода, для настройки экземпляраAppContext.
Проверка параметра
Можно проверка, если потребитель объявил значение коммутатора и действовать соответствующим образом, вызвав 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("'{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'
Однако версия 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 в "Археолог".
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
Это изменение может быть запрещено нарушать приложения, зависящие от исходного поведения, определив переключатель. В этом случае переключатель называется 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
Затем приложение платформа .NET Framework может использовать следующий файл конфигурации для восстановления поведения версии 1.0.
<configuration>
<runtime>
<AppContextSwitchOverrides value="StringLibrary.DoNotUseCultureSensitiveComparison=true" />
</runtime>
</configuration>
При запуске приложения с файлом конфигурации он создает следующие выходные данные:
'archæ' not found in 'The archaeologist'
AppContext для потребителей библиотеки
Если вы являетесь потребителем библиотеки, AppContext класс позволяет воспользоваться механизмом отказа библиотеки или метода библиотеки для новых функциональных возможностей. Отдельные методы вызываемой библиотеки классов определяют определенные коммутаторы, которые позволяют включить или отключить новое поведение. Значение параметра — логическое значение. Если это false
значение обычно является значением по умолчанию, новое поведение включено; если это true
так, новое поведение отключено, и член ведет себя так, как это было ранее.
Можно задать значение коммутатора, вызвав AppContext.SetSwitch(String, Boolean) метод в коде. Аргумент switchName
определяет имя коммутатора, а isEnabled
свойство определяет значение коммутатора. Так как AppContext это статический класс, он доступен на основе домена каждого приложения. AppContext.SetSwitch(String, Boolean) Вызов приложения область; т. е. влияет только на приложение.
платформа .NET Framework приложения имеют дополнительные способы задания значения коммутатора:
<AppContextSwitchOverrides>
Добавив элемент в <раздел среды выполнения> файла app.config. Параметр имеет один атрибут, значение которого представляет пару "ключ-значение",value
содержащую имя коммутатора и его значение.Чтобы определить несколько коммутаторов, разделите пару ключей и значений каждого коммутатора в атрибуте <элемента
value
AppContextSwitchOverrides> с запятой. В этом случае<AppContextSwitchOverrides>
элемент имеет следующий формат:<AppContextSwitchOverrides value="switchName1=value1;switchName2=value2" />
<AppContextSwitchOverrides>
Использование элемента для определения параметра конфигурации имеет приложение область; то есть это влияет только на приложение.Примечание.
Сведения о параметрах, определенных платформа .NET Framework, см<. в элементе AppContextSwitchOverrides>.
Добавив запись в реестр. Добавьте новое строковое значение в HKLM\SOFTWARE\Microsoft\. Вложенный ключ NETFramework\AppContext . Задайте имя записи именем переключателя. Задайте для его значения одно из следующих параметров:
True
, ,true
False
илиfalse
. Если среда выполнения обнаруживает любое другое значение, он игнорирует переключатель.В 64-разрядной операционной системе необходимо также добавить ту же запись в HKLM\SOFTWARE\Wow6432Node\Microsoft\. Вложенный ключ NETFramework\AppContext .
С помощью реестра для определения коммутатора AppContext есть компьютер область; то есть это влияет на каждое приложение, работающее на компьютере.
Для приложений ASP.NET и ASP.NET Core установите переключатель путем добавления <элемента Add> в <приложение Параметры> раздела файла web.config. Например:
<appSettings>
<add key="AppContext.SetSwitch:switchName1" value="switchValue1" />
<add key="AppContext.SetSwitch:switchName2" value="switchValue2" />
</appSettings>
Если один и тот же параметр задан несколькими способами, порядок приоритета для определения того, какой параметр переопределяет другие:
- Программный параметр.
- Параметр в файле app.config (для приложений платформа .NET Framework) или файла веб.config (для приложений ASP.NET Core).
- Параметр реестра (только для приложений платформа .NET Framework).