AppContext Clase
Definición
Importante
Parte de la información hace referencia a la versión preliminar del producto, que puede haberse modificado sustancialmente antes de lanzar la versión definitiva. Microsoft no otorga ninguna garantía, explícita o implícita, con respecto a la información proporcionada aquí.
Proporciona miembros para configurar y recuperar datos sobre el contexto de una aplicación.
public ref class AppContext abstract sealed
public static class AppContext
type AppContext = class
Public Class AppContext
- Herencia
-
AppContext
Comentarios
La AppContext clase permite a los escritores de bibliotecas proporcionar un mecanismo uniforme de exclusión para la nueva funcionalidad para sus usuarios. Establece un contrato flexible entre los componentes para poder comunicar una solicitud de cancelación de la participación. Esta capacidad normalmente es importante cuando se realiza un cambio en la funcionalidad existente. Por el contrario, la nueva funcionalidad participa de forma implícita.
AppContext para desarrolladores de bibliotecas
Las bibliotecas usan la AppContext clase para definir y exponer modificadores de compatibilidad, mientras que los usuarios de la biblioteca pueden establecer esos modificadores para que afecten al comportamiento de la biblioteca. De forma predeterminada, las bibliotecas proporcionan la nueva funcionalidad y solo la modifican (es decir, ofrecen la funcionalidad anterior) si el modificador está establecido. Esto permite a las bibliotecas proporcionar un nuevo comportamiento para una API existente mientras continúa admitiendo a los autores de llamadas que dependen del comportamiento anterior.
Definir el nombre del modificador
La manera más común de permitir a los consumidores de la biblioteca no participar en un cambio de comportamiento es definir un modificador con nombre. Su value
elemento es un par nombre-valor que consta del nombre de un modificador y su Boolean valor. De forma predeterminada, el modificador siempre es implícitamente false
, que proporciona el nuevo comportamiento (y hace que el nuevo comportamiento participe de forma predeterminada). Establecer el modificador en true
lo habilita, lo que proporciona el comportamiento heredado. Establecer explícitamente el modificador en false
también proporciona el nuevo comportamiento.
Es beneficioso usar un formato coherente para los nombres de modificador, ya que son un contrato formal expuesto por una biblioteca. A continuación se muestran dos formatos obvios:
Modificador.espacio de nombres.nombre del modificador
Modificador.biblioteca.nombre del modificador
Una vez que defina y documente el modificador, los autores de llamadas pueden usarlo llamando al AppContext.SetSwitch(String, Boolean) método mediante programación. .NET Framework aplicaciones también pueden usar el modificador agregando un <AppContextSwitchOverrides> elemento a su archivo de configuración de aplicación o mediante el Registro. Para obtener más información sobre cómo usan los autores de llamadas y establecer el valor de los modificadores de AppContext configuración, consulte la sección AppContext para consumidores de biblioteca .
Cuando el .NET Framework Common Language Runtime ejecuta una aplicación, lee automáticamente la configuración de compatibilidad del Registro y carga el archivo de configuración de la aplicación para rellenar la instancia de la AppContext aplicación. Dado que el autor de la llamada rellena la AppContext instancia mediante programación o el tiempo de ejecución de .NET Framework, .NET Framework las aplicaciones no tienen que realizar ninguna acción, como llamar al SetSwitch método , para configurar la AppContext instancia.
Marque el valor .
Puede comprobar si un consumidor ha declarado el valor del modificador y actuar adecuadamente llamando al AppContext.TryGetSwitch método . El método devuelve true
si se encuentra el switchName
argumento y, cuando el método devuelve, su isEnabled
argumento indica el valor del modificador. De lo contrario, el método devuelve false
.
Un ejemplo
En el ejemplo siguiente se muestra el uso de la AppContext clase para permitir al cliente elegir el comportamiento original de un método de biblioteca. A continuación se muestra la versión 1.0 de una biblioteca denominada StringLibrary
. Define un método que realiza una SubstringStartsAt
comparación ordinal para determinar el índice inicial de una subcadena dentro de una cadena mayor.
using System;
using System.Reflection;
[assembly: AssemblyVersion("1.0.0.0")]
public static class StringLibrary
{
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
A continuación, en el ejemplo siguiente se usa la biblioteca para buscar el índice inicial de la subcadena "archæ" en "El arqueológico". Dado que el método realiza una comparación ordinal, no se encuentra la subcadena.
using System;
public class Example
{
public static void Main()
{
string value = "The archaeologist";
string substring = "archæ";
int position = StringLibrary.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 Example
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'
Sin embargo, la versión 2.0 de la biblioteca cambia el SubstringStartsAt
método para usar la comparación que distingue la referencia cultural.
using System;
using System.Reflection;
[assembly: AssemblyVersion("2.0.0.0")]
public static class StringLibrary
{
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
Cuando la aplicación se vuelve a compilar para ejecutarse con la nueva versión de la biblioteca, ahora informa de que la subcadena "archæ" se encuentra en el índice 4 en "El arqueológico".
using System;
public class Example
{
public static void Main()
{
string value = "The archaeologist";
string substring = "archæ";
int position = StringLibrary.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 Example
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
Este cambio se puede impedir que rompa las aplicaciones que dependen del comportamiento original mediante la definición de un modificador. En este caso, el modificador se denomina StringLibrary.DoNotUseCultureSensitiveComparison
. Su valor predeterminado, false
, indica que la biblioteca debe realizar su comparación con la referencia cultural de la versión 2.0. true
indica que la biblioteca debe realizar su comparación ordinal de la versión 1.0. Una ligera modificación del código anterior permite al consumidor de biblioteca establecer el modificador para determinar el tipo de comparación que realiza el método.
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
Una aplicación .NET Framework puede usar el siguiente archivo de configuración para restaurar el comportamiento de la versión 1.0.
<configuration>
<runtime>
<AppContextSwitchOverrides value="StringLibrary.DoNotUseCultureSensitiveComparison=true" />
</runtime>
</configuration>
Cuando la aplicación se ejecuta con el archivo de configuración presente, genera el siguiente resultado:
'archæ' not found in 'The archaeologist'
AppContext para consumidores de bibliotecas
Si es el consumidor de una biblioteca, la AppContext clase le permite aprovechar el mecanismo de exclusión de una biblioteca o método de biblioteca para la nueva funcionalidad. Los métodos individuales de la biblioteca de clases que se llama definen modificadores concretos que habilitan o deshabilitan un nuevo comportamiento. El valor del modificador es un valor booleano. Si es false
, que suele ser el valor predeterminado, el nuevo comportamiento está habilitado; si es true
, el nuevo comportamiento está deshabilitado y el miembro se comporta como hizo anteriormente.
Puede establecer el valor de un modificador llamando al método en el AppContext.SetSwitch(String, Boolean) código. El switchName
argumento define el nombre del modificador y la isEnabled
propiedad define el valor del modificador. Dado AppContext que es una clase estática, está disponible por dominio de aplicación. Llamar a AppContext.SetSwitch(String, Boolean) tiene ámbito de aplicación; es decir, afecta solo a la aplicación.
.NET Framework aplicaciones tienen maneras adicionales de establecer el valor de un modificador:
Agregando un
<AppContextSwitchOverrides>
elemento a la <runtime> sección del archivo app.config. El modificador tiene un único atributo,value
, cuyo valor es una cadena que representa un par clave-valor que contiene el nombre del modificador y su valor.Para definir varios modificadores, separe el par clave-valor de cada conmutador en el <AppContextSwitchOverrides> atributo del
value
elemento con un punto y coma. En ese caso, el<AppContextSwitchOverrides>
elemento tiene el formato siguiente:<AppContextSwitchOverrides value="switchName1=value1;switchName2=value2" />
El uso del
<AppContextSwitchOverrides>
elemento para definir una configuración tiene ámbito de aplicación; es decir, afecta solo a la aplicación.Nota
Para obtener información sobre los modificadores definidos por .NET Framework, vea <AppContextSwitchOverrides> el elemento .
Agregando una entrada al Registro. Agregue un nuevo valor de cadena a HKLM\SOFTWARE\Microsoft\. Subclave NETFramework\AppContext . Establezca el nombre de la entrada en el nombre del modificador. Establezca su valor en una de las siguientes opciones:
True
,true
,False
ofalse
. Si el tiempo de ejecución encuentra cualquier otro valor, omite el modificador.En un sistema operativo de 64 bits, también debe agregar la misma entrada a HKLM\SOFTWARE\Wow6432Node\Microsoft\. Subclave NETFramework\AppContext .
El uso del Registro para definir un AppContext conmutador tiene ámbito de máquina; es decir, afecta a todas las aplicaciones que se ejecutan en la máquina.
Para ASP.NET y ASP.NET Core aplicaciones, establezca un modificador agregando un <Add> elemento a la <appSettings> sección del archivo web.config. Por ejemplo:
<appSettings>
<add key="AppContext.SetSwitch:switchName1" value="switchValue1" />
<add key="AppContext.SetSwitch:switchName2" value="switchValue2" />
</appSettings>
Si establece el mismo modificador en más de una manera, el orden de prioridad para determinar qué configuración invalida a los demás es:
Configuración mediante programación.
La configuración del archivo app.config (para aplicaciones .NET Framework) o el archivo de web.config (para aplicaciones de ASP.NET Core).
Configuración del Registro (solo para aplicaciones de .NET Framework).
A continuación se muestra una aplicación sencilla que pasa un URI de archivo al Path.GetDirectoryName método . Cuando se ejecuta en .NET Framework 4.6, produce un ArgumentException porque file://
ya no es una parte válida de una ruta de acceso de archivo.
using System;
using System.IO;
using System.Runtime.Versioning;
[assembly:TargetFramework(".NETFramework,Version=v4.6.2")]
public class Example
{
public static void Main()
{
Console.WriteLine(Path.GetDirectoryName("file://c/temp/dirlist.txt"));
}
}
// The example displays the following output:
// Unhandled Exception: System.ArgumentException: The path is not of a legal form.
// at System.IO.Path.NewNormalizePathLimitedChecks(String path, Int32 maxPathLength, Boolean expandShortPaths)
// at System.IO.Path.NormalizePath(String path, Boolean fullCheck, Int32 maxPathLength, Boolean expandShortPaths)
// at System.IO.Path.InternalGetDirectoryName(String path)
// at Example.Main()
module Example
open System.IO
open System.Runtime.Versioning
[<assembly: TargetFramework(".NETFramework,Version=v4.6.2")>]
do ()
Path.GetDirectoryName "file://c/temp/dirlist.txt"
|> printfn "%s"
// The example displays the following output:
// Unhandled Exception: System.ArgumentException: The path is not of a legal form.
// at System.IO.Path.NewNormalizePathLimitedChecks(String path, Int32 maxPathLength, Boolean expandShortPaths)
// at System.IO.Path.NormalizePath(String path, Boolean fullCheck, Int32 maxPathLength, Boolean expandShortPaths)
// at System.IO.Path.InternalGetDirectoryName(String path)
// at <StartupCode$ForConsumers1>.$Example.main@()
Imports System.IO
Imports System.Runtime.Versioning
<assembly:TargetFramework(".NETFramework,Version=v4.6.2")>
Module Example
Public Sub Main()
Console.WriteLine(Path.GetDirectoryName("file://c/temp/dirlist.txt"))
End Sub
End Module
' The example displays the following output:
' Unhandled Exception: System.ArgumentException: The path is not of a legal form.
' at System.IO.Path.NewNormalizePathLimitedChecks(String path, Int32 maxPathLength, Boolean expandShortPaths)
' at System.IO.Path.NormalizePath(String path, Boolean fullCheck, Int32 maxPathLength, Boolean expandShortPaths)
' at System.IO.Path.InternalGetDirectoryName(String path)
' at Example.Main()
Para restaurar el comportamiento anterior del método y evitar la excepción, puede agregar el Switch.System.IO.UseLegacyPathHandling
modificador al archivo de configuración de la aplicación para el ejemplo:
<configuration>
<runtime>
<AppContextSwitchOverrides value="Switch.System.IO.UseLegacyPathHandling=true" />
</runtime>
</configuration>
Consulte también
Propiedades
BaseDirectory |
Obtiene la ruta del archivo de acceso del directorio base que la resolución de ensamblado usa para sondear ensamblados. |
TargetFrameworkName |
Obtiene el nombre de la versión de Framework de destino de la aplicación actual. |
Métodos
GetData(String) |
Devuelve el valor del elemento de datos con nombre asignado al dominio de aplicación actual. |
SetData(String, Object) |
Establece el valor del elemento de datos con nombre asignado al dominio de aplicación actual. |
SetSwitch(String, Boolean) |
Establece el valor de un conmutador. |
TryGetSwitch(String, Boolean) |
Intenta obtener el valor de un conmutador. |