Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Este artigo fornece observações complementares à documentação de referência para esta API.
A classe AppContext permite que os escritores de bibliotecas forneçam um mecanismo de exclusão uniforme para novas funcionalidades para seus usuários. Estabelece um contrato de acoplamento frouxo entre componentes, a fim de comunicar um pedido de autoexclusão. Esse recurso geralmente é importante quando uma alteração é feita na funcionalidade existente. Por outro lado, já existe um opt-in implícito para novas funcionalidades.
AppContext para desenvolvedores de bibliotecas
As bibliotecas usam a classe AppContext para definir e expor 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 enquanto continuam a oferecer suporte a chamadores que dependem do comportamento anterior.
Definir o nome do switch
A maneira mais comum de permitir que os consumidores da sua biblioteca desativem uma mudança de comportamento é definir uma opção nomeada. O elemento value é um par nome/valor que consiste no nome de um interruptor e no valor Boolean. Por padrão, o switch é sempre falseimplícito, o que fornece o novo comportamento (e torna o novo comportamento ativado por padrão). Definir o switch como true o habilita, o que fornece o comportamento herdado. Definir explicitamente o interruptor como false também fornece o novo comportamento.
É benéfico usar um formato consistente para nomes de comutadores, uma vez que são um contrato formal exposto por uma biblioteca de software. Seguem-se dois formatos óbvios:
- Trocar. espaço para nomes. Nome do interruptor
- Comutador.biblioteca.nomedocomutador
Depois de definir e documentar o switch, os chamadores podem usá-lo chamando o método AppContext.SetSwitch(String, Boolean) programaticamente. As aplicações do .NET Framework também podem usar o switch adicionando um <AppContextSwitchOverrides> elemento ao seu ficheiro de configuração da aplicação ou utilizando o registo. Para obter mais informações sobre como os chamadores usam e definem o valor de AppContext interruptores de configuração, consulte a seção AppContext para utilizadores de bibliotecas.
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 AppContext do aplicativo. Como a instância AppContext é preenchida programaticamente pelo chamador ou pelo tempo de execução, os aplicativos do .NET Framework não precisam executar nenhuma ação, como chamar o método SetSwitch, para configurar a instância AppContext.
Verifique a configuração
Pode verificar se um utilizador declarou o valor do switch e agir de forma apropriada chamando o método AppContext.TryGetSwitch. O método retorna true se o argumento switchName for encontrado, e o seu argumento isEnabled indica o valor do interruptor. Caso contrário, o método retornará false.
Exemplo
O exemplo a seguir ilustra o uso da classe AppContext para permitir que o cliente escolha o comportamento original de um método de biblioteca. A seguir está a versão 1.0 de uma biblioteca chamada StringLibrary. Ele define um método SubstringStartsAt que executa uma comparação ordinal para determinar o índice inicial de uma substring 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 encontrar o índice inicial da substring "archæ" em "The archaeologist". Como o método executa uma comparação ordinal, a substring 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'
A versão 2.0 da biblioteca, no entanto, 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 contra a nova versão da biblioteca, ele agora relata que a substring "archæ" é encontrada no índice 4 em "O arqueólogo".
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, o switch é chamado StringLibrary.DoNotUseCultureSensitiveComparison. Seu valor padrão, false, indica que a biblioteca deve executar sua comparação sensível à cultura da versão 2.0.
true indica que a biblioteca deve realizar sua comparação ordinal da versão 1.0. Uma ligeira modificação do código anterior permite que o consumidor da biblioteca defina o switch 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 seguinte arquivo de configuração 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 bibliotecas
Caso seja o consumidor de uma biblioteca, a classe AppContext permite-lhe tirar partido do mecanismo de desativação de uma biblioteca ou método de biblioteca para novas funcionalidades. Os métodos individuais da biblioteca de classes que você está chamando definem opções específicas que habilitam ou desabilitam um novo comportamento. O valor do switch é um booleano. Se for false, que normalmente é o valor padrão, o novo comportamento será habilitado; Se for true, o novo comportamento será desativado e o membro se comportará como anteriormente.
Você pode definir o valor de um switch chamando o método AppContext.SetSwitch(String, Boolean) em seu código. O argumento switchName define o nome do switch e a propriedade isEnabled define o valor do switch. Como AppContext é uma classe estática, ela está disponível por domínio de 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>secção do ficheiro app.config. O switch tem um único atributo,value, cujo valor é uma cadeia de caracteres que representa um par chave/valor contendo o nome do switch e seu valor.Para definir múltiplos interruptores, separe o par chave/valor de cada interruptor no atributo
valuedo elemento<AppContextSwitchOverrides>, utilizando um ponto e vírgula. Nesse caso, o elemento<AppContextSwitchOverrides>tem o seguinte formato:<AppContextSwitchOverrides value="switchName1=value1;switchName2=value2" />Usar o elemento
<AppContextSwitchOverrides>para definir uma definição de configuração tem escopo de aplicativo; ou seja, afeta apenas o aplicativo.Observação
Para informações sobre os switches definidos pelo .NET Framework, veja
<AppContextSwitchOverrides>element.Adicionando uma entrada ao registo. Adicione um novo valor de cadeia de caracteres ao HKLM\SOFTWARE\Microsoft\.NETFramework\AppContext subchave. Defina o nome da entrada como o nome do comutador. Defina seu valor para uma das seguintes opções:
True,true,Falseoufalse. Se o tempo de execução encontrar qualquer outro valor, ele ignorará o interruptor.Num sistema operativo de 64 bits, deve-se também adicionar a mesma entrada à subchave HKLM\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\AppContext.
Usando o registro para definir um switch AppContext tem escopo de máquina; ou seja, afeta todos os aplicativos em execução na máquina.
Para aplicações ASP.NET e ASP.NET Core, defines um interruptor adicionando um <Add> elemento à <appSettings> secção do ficheiro web.config. Por exemplo:
<appSettings>
<add key="AppContext.SetSwitch:switchName1" value="switchValue1" />
<add key="AppContext.SetSwitch:switchName2" value="switchValue2" />
</appSettings>
Se você definir o mesmo switch de mais de uma maneira, a ordem de precedência para determinar qual configuração substitui as outras é:
- A configuração programática.
- A configuração no arquivo app.config (para aplicativos .NET Framework) ou no arquivo web.config (para aplicativos ASP.NET Core).
- A configuração do Registro (somente para aplicativos do .NET Framework).