Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Este artigo fornece comentários complementares à documentação de referência para esta API.
A classe AppContext permite que os gravadores de biblioteca forneçam um mecanismo uniforme de exclusão para novas funcionalidades para seus usuários. Ela estabelece um contrato flexível entre componentes a fim de comunicar uma solicitação de recusa. Essa funcionalidade normalmente é importante quando uma alteração é feita na funcionalidade existente. Por outro lado, já há uma aceitação implícita para novas funcionalidades.
AppContext para desenvolvedores de biblioteca
As bibliotecas usam a AppContext classe para definir e expor as opções de compatibilidade, enquanto os usuários da biblioteca podem definir essas opções para afetar o comportamento da biblioteca. Por padrão, as bibliotecas fornecem a nova funcionalidade e só a alteram (ou seja, fornecem a funcionalidade anterior) se a opção estiver definida. Isso permite que as bibliotecas forneçam um novo comportamento para uma API existente, continuando a dar suporte a chamadores que dependem do comportamento anterior.
Definir o nome do comutador
A maneira mais comum de permitir que os consumidores da sua biblioteca optem por não adotar uma alteração de comportamento é definir uma opção específica. Seu value elemento é um par nome/valor que consiste no nome de um interruptor e seu valor Boolean. Por padrão, a opção é sempre implicitamente false, o que fornece o novo comportamento (e torna o novo comportamento de aceitação padrão). Ao configurar o interruptor para true, ele será habilitado, o que fornece o comportamento herdado. Definir explicitamente o interruptor para false também proporciona o novo comportamento.
É benéfico usar um formato consistente para nomes de switch, uma vez que eles representam um contrato formal exposto por uma biblioteca. A seguir estão dois formatos óbvios:
- Alternar. namespace. nome do comutador
- Biblioteca de.comutadores.switchname
Depois de definir e documentar o alternador, os chamadores poderão usá-lo chamando o método AppContext.SetSwitch(String, Boolean) programaticamente. Os aplicativos do .NET Framework também podem usar a opção adicionando um <AppContextSwitchOverrides> elemento ao arquivo de configuração do aplicativo ou usando o registro. Para mais informações sobre como os usuários usam e definem o valor das configurações de AppContext, consulte a seção AppContext para consumidores de biblioteca.
No .NET Framework, quando o common language runtime executa um aplicativo, ele lê automaticamente as configurações de compatibilidade do Registro e carrega o arquivo de configuração do aplicativo para preencher a instância do AppContext aplicativo. Como a AppContext instância é preenchida programaticamente pelo chamador ou pelo runtime, os aplicativos do .NET Framework não precisam executar nenhuma ação, como chamar o SetSwitch método, para configurar a AppContext instância.
Verificar a configuração
Você pode verificar se um consumidor declarou o valor do comutador e agir adequadamente chamando o método AppContext.TryGetSwitch. O método retornará true se o argumento switchName for encontrado e seu respectivo argumento isEnabled indicar o valor do comutador. Caso contrário, o método retornará false.
Exemplo
O exemplo a seguir ilustra o uso da AppContext classe para permitir que o cliente escolha o comportamento original de um método de biblioteca. Veja a seguir a versão 1.0 de uma biblioteca chamada StringLibrary. Ele define um SubstringStartsAt método que executa uma comparação ordinal para determinar o índice inicial de uma subcadeia de caracteres dentro de uma cadeia de caracteres maior.
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
O exemplo a seguir usa a biblioteca para localizar o índice inicial da subcadeia de caracteres "archæ" em "O arqueólogo". Como o método executa uma comparação ordinal, a subcadeia de caracteres não pode ser encontrada.
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'
No entanto, a versão 2.0 da biblioteca altera o método SubstringStartsAt para usar a comparação sensível à cultura.
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
Quando o aplicativo é recompilado para ser executado na nova versão da biblioteca, ele agora relata que a substring "archæ" é encontrada no índice 4 em "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
Essa alteração pode ser impedida de quebrar os aplicativos que dependem do comportamento original definindo um switch. Nesse caso, a opção é nomeada StringLibrary.DoNotUseCultureSensitiveComparison. Seu valor padrão, false, indica que a biblioteca deve executar sua comparação sensível à cultura na versão 2.0.
true indica que a biblioteca deve executar sua comparação ordinal versão 1.0. Uma pequena modificação do código anterior permite que o consumidor da biblioteca defina a opção para determinar o tipo de comparação que o método executa.
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
Um aplicativo .NET Framework pode usar o arquivo de configuração a seguir para restaurar o comportamento da versão 1.0.
<configuration>
<runtime>
<AppContextSwitchOverrides value="StringLibrary.DoNotUseCultureSensitiveComparison=true" />
</runtime>
</configuration>
Quando o aplicativo é executado com o arquivo de configuração presente, ele produz a seguinte saída:
'archæ' not found in 'The archaeologist'
AppContext para consumidores de biblioteca
Se você for o consumidor de uma biblioteca, a classe AppContext permitirá que você aproveite o mecanismo de recusa de um método ou de uma biblioteca para as novas funcionalidades. Métodos individuais da biblioteca de classes que você está chamando definem comutadores específicos que habilitam ou desabilitam um novo comportamento. O valor do interruptor é um booleano. Se for false, que normalmente é o valor padrão, o novo comportamento será habilitado; se for true, o novo comportamento será desabilitado e o membro se comportará como antes.
Você pode definir o valor de um interruptor chamando o método AppContext.SetSwitch(String, Boolean) em seu código. O switchName argumento define o nome da opção e a isEnabled propriedade define o valor da opção. Como AppContext é uma classe estática, ela está disponível em uma base de domínio por aplicativo. Chamar o AppContext.SetSwitch(String, Boolean) tem escopo de aplicação; ou seja, afeta apenas o aplicativo.
Os aplicativos do .NET Framework têm maneiras adicionais de definir o valor de uma opção:
Adicionando um
<AppContextSwitchOverrides>elemento à<runtime>seção do arquivo app.config. A opção tem um único atributo,valuecujo valor é uma cadeia de caracteres que representa um par chave/valor que contém o nome da opção e seu valor.Para definir vários comutadores, separe cada par chave/valor de comutador no atributo do elemento
<AppContextSwitchOverrides>valuecom um ponto-e-vírgula. Nesse caso, o<AppContextSwitchOverrides>elemento tem o seguinte formato:<AppContextSwitchOverrides value="switchName1=value1;switchName2=value2" />Usar o
<AppContextSwitchOverrides>elemento para definir uma configuração tem o escopo do aplicativo; ou seja, afeta apenas o aplicativo.Observação
Para obter informações sobre os interruptores definidos pelo .NET Framework, consulte
<AppContextSwitchOverrides>o elemento.Adicionando uma entrada ao Registro. Adicione um novo valor de cadeia de caracteres à subchave HKLM\SOFTWARE\Microsoft\.NETFramework\AppContext. Defina o nome da entrada como o nome do interruptor. Defina seu valor como uma das seguintes opções:
True, ,true,Falseoufalse. Se o runtime encontrar qualquer outro valor, ele ignorará o comutador.Em um sistema operacional de 64 bits, você também deve adicionar a mesma entrada à subchave HKLM\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\AppContext.
Usar o registro para definir um AppContext alternador tem escopo de máquina; isto é, afeta cada aplicativo em execução na máquina.
Para aplicativos ASP.NET e ASP.NET Core, você define uma opção adicionando um <Add> elemento à <appSettings> seção do arquivo web.config. Por exemplo:
<appSettings>
<add key="AppContext.SetSwitch:switchName1" value="switchValue1" />
<add key="AppContext.SetSwitch:switchName2" value="switchValue2" />
</appSettings>
Se você definir a mesma opção em mais de uma maneira, a ordem de precedência para determinar qual configuração substitui as outras será:
- A configuração programática.
- A configuração no arquivo app.config (para aplicativos do .NET Framework) ou no arquivo web.config (para aplicativos do ASP.NET Core).
- A configuração do registro (somente para aplicativos do .NET Framework).