이 문서는 이 API에 대한 참조 설명서를 보충하는 추가 설명을 제공합니다.
이 AppContext 클래스를 사용하면 라이브러리 작성자가 사용자에게 새로운 기능을 위한 균일한 옵트아웃 메커니즘을 제공할 수 있습니다. 옵트아웃 요청을 전달하기 위해 구성 요소 간에 느슨하게 결합된 계약을 설정합니다. 이 기능은 일반적으로 기존 기능을 변경할 때 중요합니다. 반대로 새 기능에 대한 암시적 옵트인이 이미 있습니다.
라이브러리 개발자를 위한 AppContext
라이브러리는 클래스를 AppContext 사용하여 호환성 스위치를 정의하고 노출하는 반면 라이브러리 사용자는 라이브러리 동작에 영향을 주도록 해당 스위치를 설정할 수 있습니다. 기본적으로 라이브러리는 새 기능을 제공하며 스위치가 설정된 경우에만 변경합니다(즉, 이전 기능을 제공). 이렇게 하면 라이브러리가 이전 동작에 의존하는 호출자를 계속 지원하면서 기존 API에 대한 새 동작을 제공할 수 있습니다.
스위치 이름 정의
라이브러리 소비자가 동작 변경을 옵트아웃할 수 있도록 하는 가장 일반적인 방법은 명명된 스위치를 정의하는 것입니다. 해당 value
요소는 스위치 Boolean 의 이름과 해당 값으로 구성된 이름/값 쌍입니다. 기본적으로 스위치는 항상 암시적으로 false
새 동작을 제공하며 기본적으로 새 동작을 옵트인합니다. 스위치를 true
에 설정하면 레거시 동작이 활성화됩니다. 스위치를 false
로 명시적으로 설정하면 새 동작이 제공됩니다.
라이브러리에서 공개하는 공식 계약이므로 스위치 이름에 일관된 형식을 사용하는 것이 좋습니다. 다음은 두 가지 명백한 형식입니다.
- 스위치.네임스페이스. 스위치 이름
- 스위치.라이브러리.스위치 이름
스위치를 정의하고 문서화하면 호출자는 메서드를 AppContext.SetSwitch(String, Boolean) 프로그래밍 방식으로 호출하여 사용할 수 있습니다. .NET Framework 앱은 AppContextSwitchOverrides< 요소를 애플리케이션 구성 파일에 추가>하거나 레지스트리를 사용하여 스위치를 사용할 수도 있습니다. 호출자가 구성 스위치의 AppContext 값을 사용하고 설정하는 방법에 대한 자세한 내용은 라이브러리 소비자에 대한 AppContext 섹션을 참조하세요.
.NET Framework에서 공용 언어 런타임이 애플리케이션을 실행하면 레지스트리의 호환성 설정을 자동으로 읽고 애플리케이션 구성 파일을 로드하여 애플리케이션 인스턴스 AppContext 를 채웁니다. AppContext 인스턴스는 호출자 또는 런타임에 의해 프로그래밍 방식으로 채워지므로 .NET Framework 앱은 인스턴스를 구성 SetSwitch 하기 위해 메서드 호출 AppContext 과 같은 작업을 수행할 필요가 없습니다.
설정 확인
소비자가 스위치의 값을 선언했는지 확인하고, AppContext.TryGetSwitch 메서드를 호출하여 적절한 조치를 취할 수 있습니다. 인수가 true
발견되면 메서드가 반환 switchName
되고 해당 isEnabled
인수는 스위치의 값을 나타냅니다. 그렇지 않으면 메서드가 반환됩니다 false
.
예시
다음 예제에서는 클래스를 사용하여 AppContext 고객이 라이브러리 메서드의 원래 동작을 선택할 수 있도록 하는 방법을 보여 줍니다. 다음은 이름이 StringLibrary
1.0인 라이브러리의 버전 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
앱이 라이브러리의 새 버전에 대해 실행되도록 다시 컴파일되면 이제 부분 문자열 "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($"'{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
.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 앱에는 스위치의 값을 설정하는 추가 방법이 있습니다.
app.config 파일의
<AppContextSwitchOverrides>
섹션에 < 요소를 추가합니다. 스위치에는 스위치 이름과 해당 값을 모두 포함하는 키/값 쌍을 나타내는 문자열인 단일 특성value
이 있습니다.여러 스위치를 정의하려면 AppContextSwitchOverrides< 요소의 특성에서> 각 스위치의
value
키/값 쌍을 세미콜론으로 구분합니다. 이 경우 요소의<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 애플리케이션의 경우 web.config 파일의 <appSettings> 섹션에 <Add> 요소를 추가하여 스위치를 설정합니다. 다음은 그 예입니다.
<appSettings>
<add key="AppContext.SetSwitch:switchName1" value="switchValue1" />
<add key="AppContext.SetSwitch:switchName2" value="switchValue2" />
</appSettings>
둘 이상의 방법으로 동일한 스위치를 설정하는 경우 다른 설정을 재정의하는 우선 순위는 다음과 같습니다.
- 프로그래밍 방식 설정입니다.
- app.config 파일(.NET Framework 앱의 경우) 또는 web.config 파일(ASP.NET Core 앱의 경우)의 설정입니다.
- 레지스트리 설정(.NET Framework 앱에만 해당).
참고하십시오
.NET