AppContext 类
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
提供用于设置和检索有关应用程序上下文的数据的成员。
public ref class AppContext abstract sealed
public static class AppContext
type AppContext = class
Public Class AppContext
- 继承
-
AppContext
注解
该 AppContext 类使库编写者能够为其用户提供新的功能的统一选择退出机制。 它建立组件之间的松散耦合协定,以便传达选择退出请求。 当对现有功能进行更改时,此功能通常很重要。 相反,已有新功能隐式选择加入。
库开发人员的 AppContext
库使用 AppContext 类来定义和公开兼容性开关,而库用户可以设置这些开关以影响库行为。 默认情况下,库提供新功能,并且仅在设置开关时对其进行更改(即提供以前的功能)。 这样,库就可以为现有 API 提供新行为,同时继续支持依赖先前行为的调用方。
定义开关名称
允许库使用者选择退出行为更改的最常见方法是定义命名开关。 它的 value 元素是一个名称/值对,由开关的名称及其 Boolean 值组成。 默认情况下,开关总是隐式地设置为false,以提供新的行为(并默认启用新的行为)。 设置开关为true后可启用它,从而恢复旧有行为。 将此开关显式设置为 false 还将提供新行为。
使用一致的开关名称格式是有益的,因为它们是由库公开的正式协定。 以下是两种明显的格式:
- Switch.命名空间.switchname
- Switch。库。switchname
定义并记录开关后,调用方可以通过以编程方式调用 AppContext.SetSwitch(String, Boolean) 该方法来使用它。
检查设置
您可以检查用户是否已声明开关的值,并通过调用 AppContext.TryGetSwitch 方法来采取适当的操作。 如果true找到参数,该方法将返回switchName,并且其isEnabled参数指示开关的值。 否则,该方法返回 false。
示例
下面的示例演示了 AppContext 类的使用,以允许客户选择库方法的原始行为。 下面是名为 StringLibrary 的库的版本 1.0。 它定义一个 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
以下示例随后使用库在“考古学家”中查找子字符串“archæ”的起始索引。 由于该方法执行序号比较,因此找不到子字符串。
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
当重新编译应用以针对新版本的库运行时,它现在报告称在“The archaeologist”中的索引 4 处找到了子字符串“archæ”。
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> 元素添加到 web.config 文件的 <appSettings> 节来设置开关。 例如:
<appSettings>
<add key="AppContext.SetSwitch:switchName1" value="switchValue1" />
<add key="AppContext.SetSwitch:switchName2" value="switchValue2" />
</appSettings>
如果以多种方式设置相同的开关,则确定哪些设置替代其他设置的优先级顺序为:
- 编程设置。
- web.config 文件中的设置(适用于 ASP.NET Core应用)。
属性
| 名称 | 说明 |
|---|---|
| BaseDirectory |
获取程序集解析程序用于探测程序集的基目录的文件路径。 |
| TargetFrameworkName |
获取当前应用程序面向的框架版本的名称。 |
方法
| 名称 | 说明 |
|---|---|
| GetData(String) |
返回分配给当前应用程序域的命名数据元素的值。 |
| SetData(String, Object) |
设置分配给当前应用程序域的命名数据元素的值。 |
| SetSwitch(String, Boolean) |
设置开关的值。 |
| TryGetSwitch(String, Boolean) |
尝试获取开关的值。 |