AppContext 클래스

정의

애플리케이션의 컨텍스트에 대한 데이터를 설정하고 검색하기 위한 멤버를 제공합니다.

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로 명시적으로 설정하면 새 동작이 제공됩니다.

라이브러리에서 공개하는 공식 계약이므로 스위치 이름에 일관된 형식을 사용하는 것이 좋습니다. 다음은 두 가지 명백한 형식입니다.

  • 스위치.네임스페이스. 스위치 이름
  • 스위치.라이브러리.스위치 이름

스위치를 정의하고 문서화하면 호출자는 메서드를 AppContext.SetSwitch(String, Boolean) 프로그래밍 방식으로 호출하여 사용할 수 있습니다.

설정 확인

소비자가 스위치의 값을 선언했는지 확인하고, AppContext.TryGetSwitch 메서드를 호출하여 적절한 조치를 취할 수 있습니다. 인수가 true 발견되면 메서드가 반환 switchName 되고 해당 isEnabled 인수는 스위치의 값을 나타냅니다. 그렇지 않으면 메서드가 반환됩니다 false.

Example

다음 예제에서는 클래스를 사용하여 AppContext 고객이 라이브러리 메서드의 원래 동작을 선택할 수 있도록 하는 방법을 보여 줍니다. 다음은 이름이 StringLibrary1.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

라이브러리 소비자를 위한 AppContext

라이브러리 AppContext 의 소비자인 경우 클래스를 사용하면 라이브러리 또는 라이브러리 메서드의 옵트아웃 메커니즘을 활용하여 새 기능을 사용할 수 있습니다. 호출하는 클래스 라이브러리의 개별 메서드는 새 동작을 사용하거나 사용하지 않도록 설정하는 특정 스위치를 정의합니다. 스위치의 값은 부울입니다. 일반적으로 기본값인 경우 false새 동작이 활성화됩니다. 이 경우 true새 동작은 사용하지 않도록 설정되고 멤버는 이전과 같이 동작합니다.

코드에서 메서드를 호출 AppContext.SetSwitch(String, Boolean) 하여 스위치 값을 설정할 수 있습니다. 인수는 switchName 스위치 이름을 정의하고 isEnabled 속성은 스위치의 값을 정의합니다. AppContext 정적 클래스이므로 애플리케이션별 도메인 기준으로 사용할 수 있습니다. 애플리케이션 범위에서 AppContext.SetSwitch(String, Boolean)를 호출하면, 이는 애플리케이션에만 영향을 줍니다.

ASP.NET Core 애플리케이션의 경우 web.config 파일의 <Add> 섹션에 <appSettings> 요소를 추가하여 스위치를 설정합니다. 다음은 그 예입니다.

<appSettings>
   <add key="AppContext.SetSwitch:switchName1" value="switchValue1" />
   <add key="AppContext.SetSwitch:switchName2" value="switchValue2" />
</appSettings>

둘 이상의 방법으로 동일한 스위치를 설정하는 경우 다른 설정을 재정의하는 우선 순위는 다음과 같습니다.

  1. 프로그래밍 방식 설정입니다.
  2. ASP.NET Core 앱의 경우 web.config 파일의 설정입니다.

속성

Name Description
BaseDirectory

어셈블리 확인자에서 어셈블리를 검색하는 데 사용하는 기본 디렉터리의 파일 경로를 가져옵니다.

TargetFrameworkName

현재 애플리케이션이 대상으로 하는 프레임워크 버전의 이름을 가져옵니다.

메서드

Name Description
GetData(String)

현재 애플리케이션 도메인에 할당된 명명된 데이터 요소의 값을 반환합니다.

SetData(String, Object)

현재 애플리케이션 도메인에 할당된 명명된 데이터 요소의 값을 설정합니다.

SetSwitch(String, Boolean)

스위치의 값을 설정합니다.

TryGetSwitch(String, Boolean)

스위치의 값을 가져오려고 시도합니다.

적용 대상