다음을 통해 공유


.NET 기능 관리

Microsoft.FeatureManagement
Microsoft.FeatureManagement.AspNetCore
Microsoft.FeatureManagement.Telemetry.ApplicationInsights

.NET 기능 관리 라이브러리는 기능 플래그를 기반으로 애플리케이션 기능을 개발하고 노출하는 방법을 제공합니다. 새 기능이 개발될 때 많은 애플리케이션에는 기능을 사용하도록 설정해야 하는 시기 및 조건과 같은 특별한 요구 사항이 있습니다. 이 라이브러리는 이러한 관계를 정의하는 방법을 제공합니다. 또한 이러한 기능을 노출할 수 있도록 일반적인 .NET 코드 패턴과 통합됩니다.

기능 플래그는 .NET 및 ASP.NET Core 애플리케이션이 기능을 동적으로 켜거나 끄는 방법을 제공합니다. 조건문과 같은 기본 사용 사례에서 기능 플래그를 사용할 수 있습니다. 조건부 경로 추가 또는 MVC(model-view-controller) 필터와 같은 고급 시나리오에서 기능 플래그를 사용할 수도 있습니다. 기능 플래그는 .NET Core 구성 시스템 위에 빌드됩니다. 모든 .NET Core 구성 공급자는 기능 플래그의 백본 역할을 할 수 있습니다.

.NET 기능 관리 라이브러리를 사용할 경우의 이점은 다음과 같습니다.

  • 기능 관리에 일반적인 규칙을 사용합니다.
  • 진입 장벽이 낮습니다.
    • IConfiguration는 인터페이스를 기반으로 구축되었습니다.
    • JSON 파일 기능 플래그 설정을 지원합니다.
  • 기능 플래그의 수명 관리를 제공합니다.
    • 구성 값은 실시간으로 변경됩니다.
    • 기능 플래그는 전체 요청에서 일관될 수 있습니다.
  • 다음 기능에 대한 지원을 제공하여 기본적인 복잡한 시나리오를 다룹니다.
    • 선언적 구성 파일을 통해 기능 켜기 및 끄기
    • 다른 사용자에게 기능의 다양한 변형 표시
    • 서버 호출에 따라 기능의 상태를 동적으로 평가
  • 다음 영역에서 ASP.NET Core 및 MVC 프레임워크에 대한 API 확장을 제공합니다.
    • 라우팅
    • 필터
    • 작업 특성

.NET 기능 관리 라이브러리는 오픈 소스입니다. 자세한 내용은 FeatureManagement-Dotnet GitHub 리포지토리를 참조하세요.

기능 표시기

기능 플래그를 사용 또는 사용 안 함으로 설정할 수 있습니다. 기능 필터를 사용하여 플래그 상태를 조건부로 만들 수 있습니다.

기능 필터

기능 필터는 기능을 사용하도록 설정해야 하는 경우에 대한 시나리오를 정의합니다. 기능의 상태를 평가하기 위해 기능 필터 목록은 필터 중 하나가 기능이 사용 설정되었다고 결정할 때까지 탐색됩니다. 이 시점에서 기능 필터를 통한 통과가 중지됩니다. 기능을 사용하도록 설정해야 함을 나타내는 기능 필터가 없으면 사용하지 않도록 설정된 것으로 간주됩니다.

예를 들어 Microsoft Edge 브라우저 기능 필터를 디자인한다고 가정합니다. Microsoft Edge에서 HTTP 요청이 제공되면 기능 필터가 연결된 모든 기능을 활성화합니다.

기능 플래그 구성

.NET Core 구성 시스템은 기능 플래그의 상태를 결정하는 데 사용됩니다. 이 시스템의 기초는 인터페이스입니다 IConfiguration . IConfiguration에 대한 모든 공급자는 기능 플래그 라이브러리의 기능 상태 제공자로 사용될 수 있습니다. 이 시스템은 appsettings.json 구성 파일에서 Azure App Configuration에 이르는 다양한 시나리오를 지원합니다.

기능 플래그 선언

기능 관리 라이브러리는 . NET Core IConfiguration 시스템의 공급자이므로appsettings.json구성 파일을 기능 플래그 원본으로 지원합니다. 기능 플래그는 .를 사용하여 선언됩니다 Microsoft Feature Management schema. 이 스키마는 원래 언어에 구애받지 않으며 모든 Microsoft 기능 관리 라이브러리에서 지원됩니다.

다음 예제의 코드는 JSON 파일에서 기능 플래그를 선언합니다.

{
    "Logging": {
        "LogLevel": {
            "Default": "Warning"
        }
    },

    // Define feature flags in a JSON file.
    "feature_management": {
        "feature_flags": [
            {
                "id": "FeatureT",
                "enabled": false
            },
            {
                "id": "FeatureU",
                "enabled": true,
                "conditions": {}
            },
            {
                "id": "FeatureV",
                "enabled": true,
                "conditions": {
                    "client_filters": [
                        {  
                            "name": "Microsoft.TimeWindow",
                            "parameters": {
                                "Start": "Sun, 01 Jun 2025 13:59:59 GMT",
                                "End": "Fri, 01 Aug 2025 00:00:00 GMT"
                            }
                        }
                    ]
                }
            }
        ]
    }
}

JSON 문서의 섹션은 feature_management 규칙에 따라 기능 플래그 설정을 로드하는 데 사용됩니다. 이 섹션의 배열에 기능 플래그 개체를 feature_flags 나열해야 합니다. 이 코드는 세 가지 기능 플래그를 나열합니다. 각 기능 플래그 개체에는 속성 id 과 속성이 있습니다 enabled .

  • 값은 id 기능 플래그를 식별하고 참조하는 데 사용하는 이름입니다.
  • enabled 속성은 기능 플래그의 사용하도록 설정 상태를 지정합니다.

false인 경우 enabled 기능이 꺼져 있습니다. enabledtrue이면, 기능의 상태는 conditions 속성에 따라 달라집니다. 이 속성은 conditions 기능을 동적으로 사용하도록 설정하는 데 사용되는 조건을 선언합니다.

  • 기능 플래그에 속성이 conditions 없으면 기능이 켜집니다.
  • 기능 플래그에 속성이 conditions 있고 해당 조건이 충족되면 기능이 켜집니다.
  • 기능 플래그에 속성이 conditions 있고 해당 조건이 충족되지 않으면 기능이 해제됩니다.

기능 필터는 배열에 client_filters 정의됩니다. 앞의 코드에서 FeatureV 기능 플래그에는 Microsoft.TimeWindow라는 기능 필터가 있습니다. 이 필터는 구성 가능한 기능 필터의 예입니다. 이 코드에서 이 필터에는 속성이 있습니다 parameters . 이 속성은 필터를 구성하는 데 사용됩니다. 이 경우 해당 기능이 활성화되는 시작 및 종료 시간이 구성됩니다.

고급: 콜론 문자(:)는 기능 플래그 이름에서 사용할 수 없습니다.

요구 사항 유형

conditions 속성 내의 requirement_type 속성은 기능의 상태를 평가할 때 필터가 Any 논리를 사용할지 All 논리를 사용할지를 결정하기 위해 사용됩니다. requirement_type이 지정되지 않은 경우 기본값은 Any입니다. requirement_type 값은 다음과 같은 동작을 유발합니다.

  • Any: 기능을 활성화하려면 하나의 필터가 true으로 평가되어야 합니다.
  • All: 기능을 활성화하려면 모든 필터가 true로 평가되어야 합니다.

Allrequirement_type은 필터가 트래버스되는 방식 변경 내용:

  • 필터가 나열되지 않으면 기능을 사용할 수 없습니다.
  • 필터가 나열되어 있으면, 기능을 비활성화해야 한다는 조건이 지정될 때까지 순차적으로 트래버스됩니다. 기능을 사용하지 않도록 설정해야 함을 나타내는 필터가 없으면 사용하도록 설정된 것으로 간주됩니다.
{
    "id": "FeatureW",
    "enabled": true,
    "conditions": {
        "requirement_type": "All",
        "client_filters": [
            {
                "name": "Microsoft.TimeWindow",
                "parameters": {
                    "Start": "Sun, 01 Jun 2025 13:59:59 GMT",
                    "End": "Fri, 01 Aug 00:00:00 GMT"
                }
            },
            {
                "name": "Microsoft.Percentage",
                "parameters": {
                    "Value": "50"
                }
            }
        ]
    }
}

이 예제에서 FeatureW 기능 플래그는 requirement_type의 값으로 All을 가집니다. 기능을 활성화하려면 모든 필터가 true로 평가되어야 합니다. 이 경우 지정된 기간 동안 50%의 사용자에 대해 이 기능을 사용할 수 있습니다.

다중 구성 원본 처리

v4.3.0부터 Microsoft 스키마 기능 플래그(feature_management 섹션)에 대한 사용자 지정 병합을 옵트인할 수 있습니다. 동일한 기능 플래그 ID가 여러 구성 원본에 표시되면 기본 제공 ConfigurationFeatureDefinitionProvider 클래스의 인스턴스가 구성 공급자 등록 순서에 따라 해당 정의를 병합합니다. 충돌이 있는 경우 마지막 기능 플래그 정의가 사용됩니다. 이 동작은 .NET의 기본 배열 인덱스 기반 병합과 다릅니다.

다음 코드에서는 종속성 주입을 통해 사용자 지정 기능 플래그 구성을 병합할 수 있습니다.

IConfiguration configuration = new ConfigurationBuilder()
    .AddJsonFile("appsettings.json")
    .AddJsonFile("appsettings.prod.json")
    .Build();

services.AddSingleton(configuration);
services.AddFeatureManagement();
services.Configure<ConfigurationFeatureDefinitionProviderOptions>(o =>
{
        o.CustomConfigurationMergingEnabled = true;
});

다음 인스턴스 ConfigurationFeatureDefinitionProvider를 생성할 때 사용자 지정 병합을 사용하도록 설정할 수도 있습니다.

var featureManager = new FeatureManager(
    new ConfigurationFeatureDefinitionProvider(
            configuration,
            new ConfigurationFeatureDefinitionProviderOptions
            {
                    CustomConfigurationMergingEnabled = true
            }));

예제 동작:

// appsettings.json
{
    "feature_management": {
        "feature_flags": [
            { "id": "FeatureA", "enabled": true },
            { "id": "FeatureB", "enabled": false }
        ]
    }
}

// appsettings.prod.json (added later in ConfigurationBuilder)
{
    "feature_management": {
        "feature_flags": [
            { "id": "FeatureB", "enabled": true }
        ]
    }
}

** 사용자 지정 병합을 활성화하면, FeatureA는 활성화 상태를 유지하고 FeatureB는 활성화 상태로 전환됩니다. 이는 마지막 선언이 적용되기 때문입니다. 사용자 지정 병합을 사용할 수 없는 기본 .NET 병합을 사용하면 배열이 인덱스별로 병합됩니다. 원본이 위치별로 정렬되지 않는 경우 이 방법은 예기치 않은 결과를 생성할 수 있습니다.

.NET 기능 관리 스키마

이전 버전의 기능 관리 라이브러리에서 기본 스키마는 .NET 기능 관리 스키마였습니다.

라이브러리 버전 4.0.0부터 변형 및 원격 분석을 비롯한 새로운 기능은 .NET 기능 관리 스키마에서 지원되지 않습니다.

참고

기능 플래그 구성에 feature_managementFeatureManagement 섹션에 모두 나열된 선언이 포함되어 있는 경우, feature_management 섹션의 선언이 채택됩니다.

Consumption

기본 구현에서 기능 관리는 기능 플래그를 사용할 수 있는지 여부를 확인합니다. 그런 다음 결과에 따라 작업을 수행합니다. 이 검사는 IsEnabledAsyncIVariantFeatureManager 메서드를 통해 수행됩니다.

…
IVariantFeatureManager featureManager;
…
if (await featureManager.IsEnabledAsync("FeatureX"))
{
    // Do something.
}

서비스 등록

기능 관리는 .NET Core 종속성 주입을 사용합니다. 다음 코드에서 볼 수 있듯이 표준 규칙을 사용하여 기능 관리 서비스를 등록할 수 있습니다.

using Microsoft.FeatureManagement;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddFeatureManagement();
    }
}

기본적으로 기능 관리자는 .NET Core 구성 feature_management 데이터의 또는 FeatureManagement 섹션에서 기능 플래그 구성을 검색합니다. 두 섹션이 모두 없으면 구성이 비어 있는 것으로 간주됩니다.

참고

섹션 AddFeatureManagement을 전달하여 다른 구성 섹션에서 기능 플래그 구성을 검색하도록 지정할 수도 있습니다. 다음 예제에서는 기능 관리자가 MyFeatureFlags라는 섹션에서 읽도록 지정합니다.

services.AddFeatureManagement(configuration.GetSection("MyFeatureFlags"));

종속성 주입

MVC에서 기능 관리 라이브러리를 사용하는 경우 종속성 주입을 사용하여 구현하는 개체를 IVariantFeatureManager 가져올 수 있습니다.

public class HomeController : Controller
{
    private readonly IVariantFeatureManager _featureManager;
    
    public HomeController(IVariantFeatureManager featureManager)
    {
        _featureManager = featureManager;
    }
}

범위가 지정된 기능 관리 서비스

이 메서드는 AddFeatureManagement 애플리케이션 내에서 기능 관리 서비스를 싱글톤으로 추가합니다. 일부 시나리오에서는 기능 관리 서비스를 대신 범위가 지정된 서비스로 추가해야 합니다. 예를 들어, 컨텍스트 정보를 얻기 위해 범위가 지정된 서비스를 사용하는 기능 필터를 사용할 수 있습니다. 이 경우 메서드를 AddScopedFeatureManagement 사용해야 합니다. 이 메서드는 기능 필터를 포함한 기능 관리 서비스가 범위 서비스로 추가됩니다.

services.AddScopedFeatureManagement();

ASP.NET Core 통합

기능 관리 라이브러리는 웹 애플리케이션에서 일반적인 기능 플래그 시나리오를 사용하도록 설정하기 위해 ASP.NET Core 및 MVC의 기능을 제공합니다. 이러한 기능은 Microsoft.FeatureManagement.AspNetCore NuGet 패키지를 참조하여 사용할 수 있습니다.

컨트롤러 및 작업

MVC 컨트롤러 및 작업을 실행하려면 지정된 기능 또는 기능 목록 중 하나를 사용하도록 설정해야 할 수 있습니다. 개체를 사용하여 FeatureGateAttribute 이 요구 사항을 충족할 수 있습니다. FeatureGateAttribute 클래스는 Microsoft.FeatureManagement.Mvc 네임스페이스에 정의됩니다.

[FeatureGate("FeatureX")]
public class HomeController : Controller
{
    …
}

앞의 예제에서 클래스는 HomeController .에 의해 FeatureX제어됩니다. HomeController 작업은 FeatureX 기능이 사용하도록 설정된 경우에만 실행할 수 있습니다.

[FeatureGate("FeatureX")]
public IActionResult Index()
{
    return View();
}

앞의 예제에서 Index MVC 작업은 FeatureX 기능을 사용하도록 설정한 경우에만 실행할 수 있습니다.

비활성화된 작업 처리

MVC 컨트롤러 또는 동작이 지정한 기능이 활성화되지 않아 차단되면 등록된 구현 IDisabledFeaturesHandler 이 호출됩니다. 기본적으로 HTTP 404 오류를 반환하는 최소 처리기가 등록됩니다. 기능 플래그를 등록할 때 사용하여 IFeatureManagementBuilder 이 처리기를 재정의할 수 있습니다.

public interface IDisabledFeaturesHandler
{
    Task HandleDisabledFeatures(IEnumerable<string> features, ActionExecutingContext context);
}

보기

MVC 보기에서는 태그를 사용하여 <feature> 콘텐츠를 조건부로 렌더링할 수 있습니다. 기능의 사용 여부 또는 기능의 특정 변형이 할당되었는지 여부에 따라 렌더링 조건을 기반으로 할 수 있습니다. 자세한 내용은 이 문서의 뒷부분에 있는 Variants를 참조하세요.

<feature name="FeatureX">
  <p>This content appears only when 'FeatureX' is enabled.</p>
</feature>
<feature name="FeatureX" variant="Alpha">
  <p>This content appears only when variant 'Alpha' of 'FeatureX' is assigned.</p>
</feature>

기능 또는 기능 집합을 사용하지 않도록 설정할 때 콘텐츠를 표시하려는 경우 태그 도우미 평가를 부정할 수도 있습니다. 다음 예제와 같이 negate="true"을 지정하는 경우, 콘텐츠는 FeatureX이 비활성화된 경우에만 렌더링됩니다.

<feature negate="true" name="FeatureX">
  <p>This content appears only when 'FeatureX' is disabled.</p>
</feature>
<feature negate="true" name="FeatureX" variant="Alpha">
  <p>This content appears only when variant 'Alpha' of 'FeatureX' isn't assigned.</p>
</feature>

태그를 <feature> 사용하여 여러 기능을 참조할 수 있습니다. 이렇게 하려면 특성에서 쉼표로 구분된 기능 name 목록을 지정합니다.

<feature name="FeatureX,FeatureY">
  <p>This content appears only when 'FeatureX' and 'FeatureY' are enabled.</p>
</feature>

기본적으로 기능 태그를 렌더링하려면 나열된 모든 기능을 사용하도록 설정해야 합니다. 다음 예제와 같이 특성을 추가하여 requirement 이 동작을 재정의할 수 있습니다.

<feature name="FeatureX,FeatureY" requirement="Any">
  <p>This content appears only when 'FeatureX,' 'FeatureY,' or both are enabled.</p>
</feature>

태그를 <feature> 사용하여 여러 변형을 참조할 수도 있습니다. 이렇게 하려면 requirement 값으로 Any를 사용하고, variant 특성에 쉼표로 구분된 변형 목록을 지정합니다.

<feature name="FeatureX" variant="Alpha,Beta" requirement="Any">
  <p>This content appears only when variant 'Alpha' or 'Beta' of 'FeatureX' is assigned.</p>
</feature>

참고

  • 변형을 지정하는 경우 하나의 기능만 지정해야 합니다.
  • 여러 변형을 지정하고 requirement 값을 And으로 사용하면 오류가 발생합니다. 여러 변형을 할당할 수 없습니다.

<feature> 태그가 작동하려면 태그 도우미가 필요합니다. 태그를 사용하려면 _ViewImports.cshtml 파일에 기능 관리 태그 도우미를 추가합니다.

@addTagHelper *, Microsoft.FeatureManagement.AspNetCore

MVC 필터

기능의 상태에 따라 조건부로 적용하는 MVC 작업 필터를 설정할 수 있습니다. 이러한 필터를 설정하려면 기능 인식 방식으로 등록합니다. 기능 관리 파이프라인은 IAsyncActionFilter 인터페이스를 구현하는 비동기 MVC 작업 필터를 지원합니다.

services.AddMvc(o => 
{
    o.Filters.AddForFeature<SomeMvcFilter>("FeatureX");
});

위의 코드는 이름이 SomeMvcFilterMVC 필터를 등록합니다. 이 필터는 사용하도록 설정된 경우에만 FeatureX MVC 파이프라인 내에서 트리거됩니다.

Razor 페이지

MVC Razor 페이지를 실행하려면 지정된 기능 또는 기능 목록 중 하나를 사용하도록 설정해야 할 수 있습니다. 개체를 사용하여 FeatureGateAttribute 이 요구 사항을 추가할 수 있습니다. FeatureGateAttribute 클래스는 Microsoft.FeatureManagement.Mvc 네임스페이스에 정의됩니다.

[FeatureGate("FeatureX")]
public class IndexModel : PageModel
{
    public void OnGet()
    {
    }
}

앞의 코드는 FeatureX가 사용 가능해야 하는 Razor 페이지를 설정합니다. 기능을 사용하도록 설정하지 않으면 페이지에서 HTTP 404(NotFound) 결과를 생성합니다.

Razor 페이지에서 FeatureGateAttribute 개체를 사용할 때, FeatureGateAttribute을 페이지 처리기 유형에 두어야 합니다. 개별 처리기 메서드에 배치할 수 없습니다.

애플리케이션 빌드

기능 관리 라이브러리를 사용하여 기능 상태에 따라 조건부로 실행되는 애플리케이션 분기 및 미들웨어를 추가할 수 있습니다.

app.UseMiddlewareForFeature<ThirdPartyMiddleware>("FeatureX");

이전 코드에서 애플리케이션은 기능이 활성화된 경우에만 FeatureX 요청 파이프라인에 표시되는 미들웨어 구성 요소를 추가합니다. 런타임 중에 기능을 사용하거나 사용하지 않도록 설정하면 미들웨어 파이프라인을 동적으로 변경할 수 있습니다.

다음 코드에서 알 수 있듯이 이 기능은 기능을 기반으로 전체 애플리케이션을 분기하는 보다 일반적인 기능을 구축합니다.

app.UseForFeature(featureName, appBuilder => 
{
    appBuilder.UseMiddleware<T>();
});

기능 필터 구현

기능 필터를 만들면 정의한 기준에 따라 기능을 사용하도록 설정할 수 있습니다. 기능 필터를 구현하려면 인터페이스를 IFeatureFilter 구현해야 합니다. IFeatureFilter에는 EvaluateAsync라는 단일 메서드가 있습니다. 기능이 기능 필터에 대해 사용하도록 설정될 수 있음을 지정하면 EvaluateAsync 메서드가 호출됩니다. EvaluateAsync가 반환되면 true 기능을 사용하도록 설정해야 합니다.

다음 코드에서는 라는 MyCriteriaFilter사용자 지정된 기능 필터를 추가하는 방법을 보여 줍니다.

services.AddFeatureManagement()
        .AddFeatureFilter<MyCriteriaFilter>();

기능 필터는 AddFeatureManagement가 반환하는 IFeatureManagementBuilder 구현에서 AddFeatureFilter<T>를 호출하여 등록할 수 있습니다. 기능 필터는 기능 플래그를 추가하는 데 사용하는 서비스 컬렉션의 서비스에 액세스할 수 있습니다. 종속성 주입을 사용하여 이러한 서비스를 검색할 수 있습니다.

참고

기능 플래그 설정(예: appsettings.json)에서 필터를 참조하는 경우 형식 이름의 일부를 생략 Filter 해야 합니다. 자세한 내용은 이 문서의 뒷부분에 있는 필터 별칭 특성을 참조하세요.

매개 변수가 있는 기능 필터

일부 기능 필터는 기능을 켜야 하는지 여부를 평가하기 위해 매개 변수가 필요합니다. 예를 들어, 브라우저 기능 필터는 특정 브라우저 집합에 대한 기능을 켤 수 있습니다. Microsoft Edge 및 Chrome 브라우저에서는 기능을 켜고 Firefox에서는 켜지 않을 수 있습니다.

이 필터링을 구현하려면 매개 변수를 예상하도록 기능 필터를 디자인할 수 있습니다. 기능 구성에서 이러한 매개 변수를 지정합니다. 코드에서는 .의 FeatureFilterEvaluationContext매개 변수를 IFeatureFilter.EvaluateAsync 통해 액세스합니다.

public class FeatureFilterEvaluationContext
{
    /// <summary>
    /// The name of the feature being evaluated
    /// </summary>
    public string FeatureName { get; set; }

    /// <summary>
    /// The settings provided for the feature filter to use when evaluating whether the feature should be enabled
    /// </summary>
    public IConfiguration Parameters { get; set; }
}

클래스에는 Parameters라는 속성이 있는 FeatureFilterEvaluationContext가 있습니다. 이 속성의 매개 변수는 기능을 사용하도록 설정해야 하는지 여부를 평가할 때 기능 필터에서 사용할 수 있는 원시 구성을 나타냅니다. 브라우저 기능 필터 예제에서 필터는 이 속성을 사용하여 Parameters 기능에 대해 지정된 허용된 브라우저 집합을 추출할 수 있습니다. 그런 다음 필터는 요청이 해당 브라우저 중 하나에서 온 것인지 확인할 수 있습니다.

[FilterAlias("Browser")]
public class BrowserFilter : IFeatureFilter
{
    …

    public Task<bool> EvaluateAsync(FeatureFilterEvaluationContext context)
    {
        BrowserFilterSettings settings = context.Parameters.Get<BrowserFilterSettings>() ?? new BrowserFilterSettings();

        //
        // Use the settings to check whether the request is from a browser in BrowserFilterSettings.AllowedBrowsers.
    }
}

필터 별칭 속성

기능 플래그에 대한 기능 필터를 등록할 때, 구성에서 사용하는 별칭은 기능 필터 형식 이름에서 Filter 접미사가(있는 경우) 제거된 형태입니다. 구성에서 MyCriteriaFilterMyCriteria로 참조해야 합니다.

{
    "id": "MyFeature",
    "enabled": true,
    "conditions": {
        "client_filters": [
            {
                "name": "MyCriteria"
            }
        ]
    }
}

FilterAliasAttribute 클래스를 사용하여 이 이름을 재정의할 수 있습니다. 구성에서 기능 플래그 내에서 기능 필터를 참조하는 데 사용할 이름을 선언하려면 이 특성으로 기능 필터를 데코레이트할 수 있습니다.

누락된 기능 필터

특정 기능 필터에 대해 사용하도록 기능을 구성한다고 가정합니다. 기능을 평가할 때 해당 기능 필터가 등록되지 않은 경우 예외가 발생합니다. 다음 코드와 같이 기능 관리 옵션을 사용하여 예외를 사용하지 않도록 설정할 수 있습니다.

services.Configure<FeatureManagementOptions>(options =>
{
    options.IgnoreMissingFeatureFilters = true;
});

HttpContext 사용

기능 필터는 HTTP 요청의 속성에 따라 기능을 사용하도록 설정해야 하는지 여부를 평가할 수 있습니다. 이 검사는 HTTP 컨텍스트를 검사하여 수행됩니다. 다음 코드에서 알 수 있듯이 기능 필터는 종속성 주입을 사용하여 구현 IHttpContextAccessor을 가져와서 HTTP 컨텍스트에 대한 참조를 가져올 수 있습니다.

public class BrowserFilter : IFeatureFilter
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public BrowserFilter(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
    }
}

시작 시 그 구현을 사용할 수 있도록 종속성 주입 컨테이너에 IHttpContextAccessor 구현을 추가해야 합니다. 다음 메서드를 사용하여 IServiceCollection 서비스에 구현을 등록할 수 있습니다.

public void ConfigureServices(IServiceCollection services)
{
    …
    services.AddHttpContextAccessor();
    …
}

고급:IHttpContextAccessorHttpContext 서버 쪽 Blazor 앱의 Razor 구성 요소에서 사용해서는 안 됩니다. Blazor 앱에서 HTTP 컨텍스트를 전달하는 데 권장되는 방법은 데이터를 범위가 지정된 서비스로 복사하는 것입니다. Blazor 앱의 경우 기능 관리 서비스를 등록하는 데 사용해야 AddScopedFeatureManagement 합니다. 자세한 내용은 이 문서의 앞부분에 있는 스코프드 기능 관리 서비스를 참조하세요.

기능 평가를 위한 컨텍스트 제공

콘솔 애플리케이션에는 기능 필터가 기능을 켜야 하는지 여부를 확인하는 데 사용할 수 있는 것과 같은 HttpContext 앰비언트 컨텍스트가 없습니다. 이 경우 애플리케이션은 기능 필터에서 사용할 기능 관리 시스템의 컨텍스트를 나타내는 개체를 제공해야 합니다. 이 컨텍스트를 제공하는 데 사용할 IVariantFeatureManager.IsEnabledAsync<TContext>(string featureName, TContext appContext) 수 있습니다. 기능 필터는 기능의 상태를 평가하기 위해 기능 관리자에게 제공하는 개체를 사용할 appContext 수 있습니다.

MyAppContext context = new MyAppContext
{
    AccountId = current.Id
};

if (await featureManager.IsEnabledAsync(feature, context))
{
…
}

상황별 기능 필터

상황에 맞는 기능 필터는 IContextualFeatureFilter<TContext> 인터페이스를 구현합니다. 이러한 특수 기능 필터는 호출될 때 IVariantFeatureManager.IsEnabledAsync<TContext> 전달되는 컨텍스트를 활용할 수 있습니다. 형식 매개 변수는 TContext 필터에서 IContextualFeatureFilter<TContext> 처리할 수 있는 컨텍스트 형식을 설명합니다. 상황에 맞는 기능 필터를 개발할 때 컨텍스트 형식을 지정하여 필터 사용에 대한 요구 사항을 설정할 수 있습니다.

모든 형식은 클래스의 Object 하위 항목이므로 제공된 컨텍스트에 대해 구현하는 IContextualFeatureFilter<object> 필터를 호출할 수 있습니다. 다음 코드는 특정 컨텍스트 기능 필터의 예를 제공합니다. 이 코드에서는 계정이 구성된 사용 계정 목록에 있는 경우 기능을 사용할 수 있습니다.

public interface IAccountContext
{
    string AccountId { get; set; }
}

[FilterAlias("AccountId")]
class AccountIdFilter : IContextualFeatureFilter<IAccountContext>
{
    public Task<bool> EvaluateAsync(FeatureFilterEvaluationContext featureEvaluationContext, IAccountContext accountId)
    {
        //
        // Evaluate whether the feature should be on by using the IAccountContext that's provided.
    }
}

AccountIdFilter 클래스는 기능의 상태를 평가할 수 있도록 IAccountContext를 구현한 개체가 제공되어야 합니다. 이 기능 필터를 사용할 때, 호출자는 전달된 객체가 IAccountContext을(를) 구현하는지 확인해야 합니다.

참고

단일 형식에서는 단일 기능 필터 인터페이스만 구현할 수 있습니다. 둘 이상의 기능 필터 인터페이스를 구현하는 기능 필터를 추가하려고 하면 예외가 발생합니다 ArgumentException .

동일한 별칭을 사용하여 상황별 필터 및 비 컨텍스트 필터 사용

IFeatureFilterIContextualFeatureFilter을 구현할 수 있는 필터는 동일한 별칭을 공유할 수 있습니다. 특히 적용 가능한 필터가 하나 이상 있는 경우 0개 또는 1개의 IFeatureFilter 구현과 0 또는 NIContextualFeatureFilter<ContextType> 구현에서 공유하는 하나의 필터 별칭을 ContextType가질 수 있습니다.

동일한 이름의 컨텍스트 필터와 비 컨텍스트 필터가 애플리케이션에 등록될 때 필터를 선택하는 프로세스를 이해하려면 다음 예제를 고려하세요.

세 개의 필터는 별칭을 SharedFilterName 공유합니다.

  • FilterA라는 컨텍스트상 관련이 없는 필터
  • TypeB 컨텍스트를 허용하는 FilterB라는 컨텍스트 필터
  • FilterC라는 컨텍스트 필터는 TypeC 컨텍스트를 허용합니다.

호출된 MyFeature 기능 플래그는 해당 구성에서 SharedFilterName 기능 필터를 사용합니다.

세 필터가 모두 등록된 경우:

  • IsEnabledAsync("MyFeature")을(를) 호출하면 FilterA 필터가 기능 플래그를 평가하는 데 사용됩니다.
  • IsEnabledAsync("MyFeature", context)를 호출할 때:
    • context의 유형이 TypeB인 경우, FilterB가 사용됩니다.
    • context의 유형이 TypeC이면, FilterC가 사용됩니다.
    • 형식이 context이고 TypeF이면 FilterA가 사용됩니다.

기본 제공 기능 필터

패키지 Microsoft.FeatureManagement에는 몇 가지 기능 필터가 있으며, PercentageFilter, TimeWindowFilter, ContextualTargetingFilterTargetingFilter가 포함됩니다. 이 메서드를 사용하여 기능 관리를 등록하는 경우를 제외한 TargetingFilter 모든 필터가 AddFeatureManagement 추가됩니다. TargetingFilterWithTargeting 메서드를 사용하여 추가됩니다. 자세한 내용은 이 문서의 뒷부분에 있는 대상 지정을 참조하세요.

기본 제공된 각 기능 필터에는 고유한 매개 변수가 있습니다. 다음 섹션에서는 이러한 기능 필터에 대해 설명하고 예제를 제공합니다.

Microsoft.Percentage

필터는 Microsoft.Percentage 설정된 백분율에 따라 기능을 사용하도록 설정하는 방법을 제공합니다.

{
    "id": "EnhancedPipeline",
    "enabled": true,
    "conditions": {
        "client_filters": [
            {
                "name": "Microsoft.Percentage",
                "parameters": {
                    "Value": 50
                }
            }
        ]
    }
}

Microsoft.TimeWindow

필터는 Microsoft.TimeWindow 시간 창에 따라 기능을 사용하도록 설정하는 방법을 제공합니다.

  • 값만 End 지정하면 해당 시간까지 기능이 고려됩니다.
  • 값만 Start 지정하면 해당 시간 이후의 모든 지점에서 기능이 고려됩니다.
{
    "id": "EnhancedPipeline",
    "enabled": true,
    "conditions": {
        "client_filters": [
            {
                "name": "Microsoft.TimeWindow",
                "parameters": {
                    "Start": "Sun, 01 Jun 2025 13:59:59 GMT",
                    "End": "Fri, 01 Aug 2025 00:00:00 GMT"
                }
            }
        ]
    }
}

반복적으로 시간 창을 적용하도록 필터를 구성할 수 있습니다. 이 기능은 트래픽이 적거나 트래픽이 많은 기간 또는 요일 또는 특정 요일 동안 기능을 켜야 하는 경우에 유용할 수 있습니다. 개별 시간 창을 되풀이 시간 창으로 확장하려면 매개 변수를 Recurrence 사용하여 되풀이 규칙을 지정합니다.

참고

되풀이를 사용하려면 값을 지정 StartEnd 해야 합니다. 되풀이를 사용하면 값의 End 날짜 부분이 필터 활성을 고려하기 위한 종료 날짜를 지정하지 않습니다. 대신 필터는 시작 날짜를 기준으로 종료 날짜를 사용하여 되풀이되는 기간의 기간을 정의합니다.

{
    "id": "EnhancedPipeline",
    "enabled": true,
    "conditions": {
        "client_filters": [
            {
                "name": "Microsoft.TimeWindow",
                "parameters": {
                    "Start": "Fri, 22 Mar 2024 20:00:00 GMT",
                    "End": "Sat, 23 Mar 2024 02:00:00 GMT",
                    "Recurrence": {
                        "Pattern": {
                            "Type": "Daily",
                            "Interval": 1
                        },
                        "Range": {
                            "Type": "NoEnd"
                        }
                    }
                }
            }
        ]
    }
}

설정은 Recurrence 다음 두 부분으로 구성됩니다.

  • 설정은 Pattern 시간 창 반복 빈도를 지정합니다.
  • 이 설정은 Range 되풀이 패턴이 반복되는 기간을 지정합니다.

되풀이 방법

가능한 되풀이 방법 형식은 DailyWeekly 두 가지입니다. 예를 들어 시간 창은 매일, 3일마다, 매주 월요일 또는 매주 금요일에 반복할 수 있습니다.

형식에 따라 설정의 특정 필드가 Pattern 필수, 선택 사항 또는 무시됩니다.

  • Daily

    일별 되풀이 패턴은 각 발생 사이의 지정된 일 수에 따라 시간 창이 반복되도록 합니다.

    속성 관련성 설명
    Type 필수 되풀이 패턴 형식입니다. Daily로 설정해야 합니다.
    Interval 옵션 각 발생 사이의 일 수입니다. 기본값은 1입니다.
  • Weekly

    주별 되풀이 패턴은 시간 창이 같은 요일에 반복되도록 합니다. 그러나 각 발생 집합 사이의 주 수를 지정할 수 있습니다.

    속성 관련성 설명
    Type 필수 되풀이 패턴 형식입니다. Weekly로 설정해야 합니다.
    DaysOfWeek 필수 이벤트가 발생하는 요일입니다.
    Interval 옵션 각 발생 집합 사이의 주 수입니다. 기본값은 1입니다.
    FirstDayOfWeek 옵션 요일의 첫째 날로 사용할 날짜입니다. 기본값은 Sunday입니다.

    다음 예제에서는 매주 월요일과 화요일에 시간 창을 반복합니다.

    "Pattern": {
        "Type": "Weekly",
        "Interval": 2,
        "DaysOfWeek": ["Monday", "Tuesday"]
    }
    

참고

값은 Start 되풀이 패턴에 맞는 유효한 첫 번째 항목이어야 합니다. 또한 기간 기간은 발생 빈도보다 길 수 없습니다. 예를 들어 25시간 기간은 매일 되풀이할 수 없습니다.

되풀이 범위

되풀이 범위 유형에는 다음과 같은 세 가지NoEndEndDateNumbered가 있습니다.

  • NoEnd

    NoEnd 범위로 인해 되풀이가 무기한 발생합니다.

    속성 관련성 설명
    Type 필수 되풀이 범위 형식입니다. NoEnd로 설정해야 합니다.
  • EndDate

    EndDate 범위를 사용하면 종료 날짜까지 적용 가능한 패턴에 맞는 모든 날짜에 기간이 발생합니다.

    속성 관련성 설명
    Type 필수 되풀이 범위 형식입니다. EndDate로 설정해야 합니다.
    EndDate 필수 패턴 적용을 중지할 날짜 및 시간입니다. 마지막 발생의 시작 시간이 종료 날짜 이전인 경우 해당 발생의 종료 시간이 그 이상으로 확장할 수 있습니다.

    다음 예제에서 시간 창은 2024년 4월 1일에 마지막으로 발생할 때까지 매일 반복됩니다.

    "Start": "Fri, 22 Mar 2024 18:00:00 GMT",
    "End": "Fri, 22 Mar 2024 20:00:00 GMT",
    "Recurrence":{
        "Pattern": {
            "Type": "Daily",
            "Interval": 1
        },
        "Range": {
            "Type": "EndDate",
            "EndDate": "Mon, 1 Apr 2024 20:00:00 GMT"
        }
    }
    
  • Numbered

    Numbered 범위는 시간 창이 지정된 횟수만큼 발생하도록 합니다.

    속성 관련성 설명
    Type 필수 되풀이 범위 형식입니다. Numbered로 설정해야 합니다.
    NumberOfOccurrences 필수 발생 횟수입니다.

    다음 예시에서 시간 창은 총 3번 발생하며, 월요일과 화요일에 반복됩니다.

    • 4월 1일 월요일
    • 4월 2일 화요일
    • 4월 8일 월요일
    "Start": "Mon, 1 Apr 2024 18:00:00 GMT",
    "End": "Mon, 1 Apr 2024 20:00:00 GMT",
    "Recurrence":{
        "Pattern": {
            "Type": "Weekly",
            "Interval": 1,
            "DaysOfWeek": ["Monday", "Tuesday"]
        },
        "Range": {
            "Type": "Numbered",
            "NumberOfOccurrences": 3
        }
    }
    

되풀이 규칙을 만들려면 PatternRange 두 설정을 모두 지정해야 합니다. 모든 패턴 형식은 모든 범위 형식에서 작동할 수 있습니다.

고급:Start 속성의 표준 시간대 오프셋이 되풀이 설정에 적용됩니다.

Microsoft.Targeting

필터는 Microsoft.Targeting 대상 대상 그룹에 기능을 사용하도록 설정하는 방법을 제공합니다. 대상 지정에 대한 자세한 설명은 이 문서의 뒷부분에 있는 대상 지정을 참조하세요.

필터 매개 변수에는 기능에 대한 액세스 권한이 있는 사용자를 설명하는 개체가 포함 Audience 됩니다. Audience 개체 내에서 사용자, 그룹, 제외된 사용자 및 그룹 및 사용자 기반의 기본 비율을 지정할 수 있습니다.

섹션에 나열된 각 그룹 개체에 Groups 대해 액세스 권한이 있어야 하는 그룹 구성원의 백분율도 지정해야 합니다.

각 사용자에 대해 기능은 다음과 같은 방식으로 평가됩니다.

  • 사용자가 제외된 경우 이 기능은 사용자에 대해 사용하지 않도록 설정됩니다. 다음을 통해 사용자를 제외할 수 있습니다.

    • Exclusion 섹션의 Users 아래에 이름을 나열합니다.
    • 그들이 속하는 그룹을 Exclusion 섹션의 Groups 아래에 나열합니다.
  • 사용자가 제외되지 않으면 다음 조건 중 하나라도 충족되는 경우 이 기능이 활성화됩니다.

    • 사용자가 Users 섹션에 포함되어 있습니다.
    • 사용자가 모든 그룹 롤아웃에 포함된 비율에 속해 있습니다.
    • 사용자는 기본 롤아웃 백분율에 속합니다.
  • 이전 사례가 적용되지 않는 경우 해당 기능은 사용자에 대해 사용하지 않도록 설정됩니다. 예를 들어 사용자가 포함된 백분율에 없는 경우 기능을 사용할 수 없습니다.

{
    "id": "EnhancedPipeline",
    "enabled": true,
    "conditions": {
        "client_filters": [
            {
                "name": "Microsoft.Targeting",
                "parameters": {
                    "Audience": {
                        "Users": [
                            "Jeff",
                            "Alicia"
                        ],
                        "Groups": [
                            {
                                "Name": "Ring0",
                                "RolloutPercentage": 100
                            },
                            {
                                "Name": "Ring1",
                                "RolloutPercentage": 50
                            }
                        ],
                        "DefaultRolloutPercentage": 20,
                        "Exclusion": {
                            "Users": [
                                "Ross"
                            ],
                            "Groups": [
                                "Ring2"
                            ]
                        }
                    }
                }
            }
        ]
    }
}

기능 필터 별칭 네임스페이스

모든 내장 기능 필터 별칭은 Microsoft 기능 필터 네임스페이스에 있습니다. 이 네임스페이스에 있으면 동일한 별칭을 공유하는 다른 기능 필터와의 충돌을 방지할 수 있습니다. 기능 필터 네임스페이스의 세그먼트는 문자로 . 분할됩니다. 기능 필터는 정규화된 별칭(예: Microsoft.Percentage)으로 참조할 수 있습니다. 또는 마지막 세그먼트(예: Percentage.)를 참조할 수 있습니다.

대상 지정

대상 지정은 사용자 기반에 새 기능을 점진적으로 롤아웃하는 데 사용할 수 있는 기능 관리 전략입니다. 이 전략은 대상 그룹으로 알려진 일련의 사용자를 대상으로 지정한다는 개념을 바탕으로 빌드되었습니다. 대상 그룹은 특정 사용자, 그룹, 제외된 사용자 및 그룹 및 전체 사용자 기반의 지정된 백분율로 구성됩니다. 대상 그룹에 포함된 그룹은 전체 멤버의 비율로 더 세분화될 수 있습니다.

다음 단계에서는 베타라는 새 기능에 대한 점진적 롤아웃의 예를 보여 줍니다.

  1. 개별 사용자인 Jeff와 Alicia에게 베타 기능에 대한 액세스 권한이 부여됩니다.
  2. 다른 사용자인 Mark가 옵트인을 요청하여 포함되었습니다.
  3. Ring1 그룹의 사용자 중 20%가 베타 기능에 포함되어 있습니다.
  4. 포함된 Ring1 사용자 수는 최대 100%까지 증가합니다.
  5. 사용자 기반의 5%가 베타 기능에 포함됩니다.
  6. 롤아웃 비율은 기능을 완전히 롤아웃하기 위해 최대 100%까지 증가합니다.

라이브러리는 기본 제공 Microsoft.Targeting 기능 필터를 통해 기능을 롤아웃하기 위한 이 전략을 지원합니다.

웹 애플리케이션의 대상 지정

대상 지정 기능 필터를 사용하는 웹 애플리케이션의 예제는 FeatureFlagDemo 예제 프로젝트를 참조하세요.

애플리케이션에서 사용을 TargetingFilter 시작하려면 다른 기능 필터와 마찬가지로 애플리케이션의 서비스 컬렉션에 추가해야 합니다. 다른 기본 제공 필터와 TargetingFilter 달리 다른 서비스를 사용하여 애플리케이션의 서비스 컬렉션에 추가합니다. 해당 서비스는 하나의 ITargetingContextAccessor 구현입니다.

라이브러리는 Microsoft.FeatureManagement.AspNetCore 요청 ITargetingContextAccessor 에서 대상 정보를 추출하는 HttpContext을 제공합니다. 기본 대상 지정 컨텍스트 접근자는 IFeatureManagementBuilder에 대한 비제네릭 WithTargeting 오버로드를 사용하여 대상 지정을 설정할 때 사용할 수 있습니다.

기본 대상 지정 컨텍스트 접근자와 TargetingFilter를 등록하려면 IFeatureManagementBuilder에서 WithTargeting을 호출합니다.

services.AddFeatureManagement()
        .WithTargeting();

WithTargeting<T>을 호출하여 ITargetingContextAccessorTargetingFilter에 대한 사용자 지정된 구현을 등록할 수도 있습니다. 다음 코드는 ITargetingContextAccessor의 구현인 ExampleTargetingContextAccessor을 사용하는 TargetingFilter 기능 관리를 웹 애플리케이션에 설정합니다.

services.AddFeatureManagement()
        .WithTargeting<ExampleTargetingContextAccessor>();

ITargetingContextAccessor

웹 애플리케이션에서 TargetingFilter을 사용하려면 ITargetingContextAccessor의 구현이 필요합니다. 이 요구 사항의 원인은 사용자에 대한 정보와 같은 컨텍스트 정보가 대상 평가에 필요하다는 것입니다. 이 정보는 클래스의 TargetingContext 인스턴스에 저장됩니다. 다른 애플리케이션은 요청의 HTTP 컨텍스트 또는 데이터베이스와 같은 여러 위치에서 이 정보를 추출합니다.

애플리케이션의 HTTP 컨텍스트에서 대상 컨텍스트 정보를 추출하는 예제는 Microsoft.FeatureManagement.AspNetCore 패키지의 DefaultHttpTargetingContextAccessor를 참조하세요. 다음 정보를 추출합니다.

  • HttpContext.User 속성의 대상 지정 정보
  • UserId 필드의 Identity.Name 정보
  • Groups 클레임 유형의 정보 Role

이 구현은 .의 IHttpContextAccessor사용에 의존합니다. 자세한 IHttpContextAccessor내용은 이 문서의 앞부분에 있는 HttpContext 사용을 참조하세요.

콘솔 애플리케이션의 대상 지정

대상 지정 필터는 대상 지정 컨텍스트를 사용하여 기능을 켜야 하는지 여부를 평가합니다. 이 대상 지정 컨텍스트에는 평가 중인 사용자 및 사용자가 속한 그룹과 같은 정보가 포함됩니다. 콘솔 애플리케이션에서는 일반적으로 대상 지정 필터에 이 정보를 전달하는 데 사용할 수 있는 앰비언트 컨텍스트가 없습니다. 따라서 호출 FeatureManager.IsEnabledAsync할 때 직접 전달해야 합니다. 이 유형의 컨텍스트는 ContextualTargetingFilter을 사용하여 지원됩니다. 기능 관리자에 대상 지정 컨텍스트를 보내야 하는 애플리케이션은 다음 대신 사용해야 ContextualTargetingFilter 합니다. TargetingFilter.

ContextualTargetingFilterIContextualTargetingFilter<ITargetingContext>를 구현하므로, 기능을 평가하고 활성화할 수 있도록 ITargetingContext의 구현을 IVariantFeatureManager.IsEnabledAsync에 전달해야 합니다.

IVariantFeatureManager fm;
…
// The userId and groups variables are defined earlier in the application.
TargetingContext targetingContext = new TargetingContext
{
   UserId = userId,
   Groups = groups
};

await fm.IsEnabledAsync(featureName, targetingContext);

ContextualTargetingFilter 는 기능 필터 별칭을 Microsoft.Targeting사용하므로 이 필터에 대한 구성은 이 문서의 앞부분에 있는 Microsoft.Targeting의 정보와 일치합니다.

콘솔 애플리케이션에서 사용하는 ContextualTargetingFilter 예제는 TargetingConsoleApp 예제 프로젝트를 참조하세요.

평가 옵션 대상 지정

모든 기능에 걸쳐 대상 평가가 수행되는 방식을 사용자 지정하는 옵션을 사용할 수 있습니다. 기능 관리를 설정할 때 이러한 옵션을 구성할 수 있습니다.

services.Configure<TargetingEvaluationOptions>(options =>
{
    options.IgnoreCase = true;
});

대상 지정 제외

대상 그룹을 정의할 때 대상 그룹에서 사용자 및 그룹을 제외할 수 있습니다. 이 기능은 사용자 그룹에 기능을 롤아웃할 때 유용하지만 롤아웃에서 몇 명의 사용자 또는 그룹을 제외해야 합니다. 제외할 사용자 및 그룹을 지정하려면 대상 그룹의 속성을 사용합니다 Exclusion .

"Audience": {
    "Users": [
        "Jeff",
        "Alicia"
    ],
    "Groups": [
        {
            "Name": "Ring0",
            "RolloutPercentage": 100
        }
    ],
    "DefaultRolloutPercentage": 0,
    "Exclusion": {
        "Users": [
            "Mark"
        ]
    }
}

이 코드는 JeffAlicia로 명명된 사용자에 대한 기능을 활성화합니다. 이 기능은 그룹의 사용자에 대해서도 사용하도록 설정됩니다 Ring0. 그러나 사용자 이름이 Mark일 경우, 그 사용자가 Ring0 그룹에 속해 있더라도 이 기능은 비활성화됩니다. 제외는 나머지 대상 지정 필터보다 우선 순위가 높습니다.

변형

경우에 따라 애플리케이션에 새 기능을 추가할 때 이 기능에는 여러 가지 제안된 디자인 옵션이 있습니다. A/B 테스트는 디자인을 결정하기 위한 일반적인 솔루션을 제공합니다. A/B 테스트에는 사용자 기반의 여러 세그먼트에 다른 버전의 기능을 제공한 다음 사용자 상호 작용에 따라 버전을 선택하는 작업이 포함됩니다. .NET 기능 관리 라이브러리에서 변형을 사용하여 기능의 다양한 구성을 나타내는 A/B 테스트를 구현할 수 있습니다.

변형은 기능 플래그가 기본 온/오프 플래그 이상이 되는 방법을 제공합니다. 변형은 문자열, 숫자, 부울 또는 구성 개체일 수 있는 기능 플래그의 값을 나타냅니다. 변형을 선언하는 기능 플래그는 각 변형을 사용해야 하는 상황을 정의해야 합니다. 자세한 내용은 이 문서의 뒷부 분에 있는 변형 할당을 참조하세요.

public class Variant
{
    /// <summary>
    /// The name of the variant
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// The configuration of the variant
    /// </summary>
    public IConfigurationSection Configuration { get; set; }
}

변형 검색

각 기능별로, 인터페이스의 IVariantFeatureManager 메서드를 사용하여 GetVariantAsync 변형을 검색할 수 있습니다.

…
IVariantFeatureManager featureManager;
…
Variant variant = await featureManager.GetVariantAsync("MyVariantFeatureFlag", CancellationToken.None);

IConfigurationSection variantConfiguration = variant.Configuration;

// Do something with the resulting variant and its configuration.

변형을 검색한 후, 해당 변형의 Configuration 속성을 통해 변형의 구성을 IConfigurationSection의 구현으로 직접 사용할 수 있습니다. 또 다른 옵션은 .NET 구성 바인딩 패턴을 사용하여 구성을 개체에 바인딩하는 것입니다.

IConfigurationSection variantConfiguration = variant.Configuration;

MyFeatureSettings settings = new MyFeatureSettings();

variantConfiguration.Bind(settings);

반환되는 변형은 평가 중인 사용자에 따라 달라집니다. 인스턴스 TargetingContext에서 사용자에 대한 정보를 가져올 수 있습니다. 를 호출 GetVariantAsync할 때 이 컨텍스트를 전달할 수 있습니다. 또는 ITargetingContextAccessor 구현이 등록되어 있는 경우, 해당 구현에서 자동으로 검색할 수도 있습니다.

변형 기능 플래그 선언

표준 기능 플래그에 비해 변형 기능 플래그에는 두 가지 추가 속성 variants 이 있습니다 allocation. 속성은 variants 기능에 대해 정의된 변형을 포함하는 배열입니다. allocation 속성은 이러한 변형을 기능에 할당하는 방법을 정의합니다. 표준 기능 플래그를 선언하는 것과 마찬가지로 JSON 파일에서 변형 기능 플래그를 설정할 수 있습니다. 다음 코드는 변형 기능 플래그의 예입니다.

{
    "feature_management": {
        "feature_flags": [
            {
                "id": "MyVariantFeatureFlag",
                "enabled": true,
                "allocation": {
                    "default_when_enabled": "Small",
                    "group": [
                        {
                            "variant": "Big",
                            "groups": [
                                "Ring1"
                            ]
                        }
                    ]
                },
                "variants": [
                    { 
                        "name": "Big"
                    },  
                    { 
                        "name": "Small"
                    } 
                ]
            }
        ]
    }
}

변형 정의

각 변형에는 이름과 구성이라는 두 가지 속성이 있습니다. 이름은 특정 변형을 참조하는 데 사용되며 구성은 해당 변형의 값입니다. 속성을 사용하여 configuration_value 구성을 지정할 수 있습니다. 이 configuration_value 속성은 문자열, 숫자, 부울 또는 구성 개체일 수 있는 인라인 구성입니다. configuration_value 속성을 구성하지 않으면, 반환된 variant의 Configuration 속성은 null입니다.

기능에 대해 가능한 모든 변형을 지정하려면 속성 아래에 나열합니다 variants .

{
    "feature_management": {
        "feature_flags": [
            {
                "id": "MyVariantFeatureFlag",
                "variants": [
                    { 
                        "name": "Big", 
                        "configuration_value": {
                            "Size": 500
                        }
                    },  
                    { 
                        "name": "Small", 
                        "configuration_value": {
                            "Size": 300
                        }
                    } 
                ]
            }
        ]
    }
}

버전 할당

기능의 변형을 할당하려면 기능의 allocation 속성을 사용합니다.

"allocation": { 
    "default_when_enabled": "Small", 
    "default_when_disabled": "Small",  
    "user": [ 
        { 
            "variant": "Big", 
            "users": [ 
                "Marsha" 
            ] 
        } 
    ], 
    "group": [ 
        { 
            "variant": "Big", 
            "groups": [ 
                "Ring1" 
            ] 
        } 
    ],
    "percentile": [ 
        { 
            "variant": "Big", 
            "from": 0, 
            "to": 10 
        } 
    ], 
    "seed": "13973240" 
},
"variants": [
    { 
        "name": "Big", 
        "configuration_value": "500px"
    },  
    { 
        "name": "Small", 
        "configuration_value": "300px"
    } 
]

설정에는 allocation 다음과 같은 속성이 있습니다.

속성 설명
default_when_disabled 기능이 비활성화된 것으로 간주되는 동안 변형이 요청될 때 사용할 변형입니다.
default_when_enabled 기능이 활성화된 것으로 간주되고 다른 변형이 사용자에게 할당되지 않는 동안 변형이 요청될 때 사용할 변형입니다.
user 변형과 변형을 할당할 사용자 목록입니다.
group 변형 및 그룹 목록입니다. 현재 사용자가 그룹 중 하나 이상에 있는 경우 변형이 할당됩니다.
percentile 변형이 할당되기 위해 사용자의 계산된 백분율이 들어맞아야 하는 변형과 백분율 범위입니다.
seed 백분율 계산을 percentile 기반으로 하는 값입니다. 동일한 값을 사용하는 경우 특정 사용자에 대한 백분율 계산은 모든 기능에서 동일합니다 seed . seed 값을 지정하지 않으면, 특징 이름에 따라 기본 시드가 만들어집니다.

기능을 사용하도록 설정하지 않으면 기능 관리자는 현재 사용자에게 지정된 default_when_disabled 변형을 할당합니다. 앞의 예제에서 해당 기능을 호출 Small합니다.

기능이 사용하도록 설정된 경우 기능 관리자는 변형을 할당하기 위해 user, grouppercentile 할당을 순서대로 확인합니다. 앞의 예제에서 지정된 변형 Big은 다음과 같은 경우에 사용자에게 할당됩니다.

  • 평가 중인 사용자의 이름이 지정 Marsha됩니다.
  • 사용자가 Ring1 그룹에 있습니다.
  • 사용자는 0에서 10번째 백분위수 사이에 떨어집니다.

이러한 할당이 일치하지 않으면 default_when_enabled 변형 항목이 사용자에게 할당됩니다. 예제에서 해당 변형은 .입니다 Small.

할당 논리는 Microsoft.Targeting 기능 필터에 사용하는 논리와 유사합니다. 그러나 할당에 없는 대상 지정에 있는 몇 가지 매개 변수가 있으며 그 반대의 경우도 마찬가지입니다. 대상 지정과 할당의 결과는 관련이 없습니다.

참고

기능 변형을 할당하려면 ITargetingContextAccessor를 등록하기 위해 WithTargeting<T> 메서드를 호출해야 합니다.

변형을 사용하여 사용 상태를 재정의

변형을 사용하여 기능 플래그의 사용하도록 설정 상태를 재정의할 수 있습니다. 이 기능을 활용하면 기능 플래그의 평가를 확장할 수 있습니다. 변형이 있는 플래그를 호출하는 IsEnabledAsync 동안 기능 관리자는 현재 사용자에게 할당된 변형이 결과를 재정의하도록 구성되어 있는지 확인합니다.

선택적 variant 속성을 status_override사용하여 재정의를 구현할 수 있습니다. 이 속성에는 다음 값이 있을 수 있습니다.

  • None: 변형은 플래그가 사용 또는 비활성화된 것으로 간주되는지 여부에 영향을 주지 않습니다. None 는 기본값입니다.
  • Enabled: 변형을 선택하면 기능 플래그가 사용으로 평가됩니다.
  • Disabled: 변형을 선택하면 기능 플래그가 비활성화된 것으로 평가됩니다.

enabled 상태가 false인 기능은 재정의할 수 없습니다.

이진 변형이 있는 기능 플래그를 사용하는 경우 이 속성이 status_override 유용할 수 있습니다. 애플리케이션에서 IsEnabledAsyncFeatureGateAttribute와 같은 API를 계속 사용할 수 있습니다. 그러나 백분위수 할당 및 백분율 계산에 초기값 사용과 같은 변형과 함께 제공되는 기능을 활용할 수도 있습니다.

{
    "id": "MyVariantFeatureFlag",
    "enabled": true,
    "allocation": {
        "percentile": [
            {
                "variant": "On",
                "from": 10,
                "to": 20
            }
        ],
        "default_when_enabled":  "Off",
        "seed": "Enhanced-Feature-Group"
    },
    "variants": [
        {
            "name": "On"
        },
        {
            "name": "Off",
            "status_override": "Disabled"
        }
    ]
}

앞의 예제에서 기능은 항상 사용하도록 설정됩니다. 현재 사용자가 계산된 백분위수 범위가 10에서 20인 경우 변형이 On 반환됩니다. 그렇지 않으면 변형이 Off 반환되고 값이 status_override 값이므로 Disabled기능이 비활성화된 것으로 간주됩니다.

종속성 주입의 다양성

종속성 주입과 함께 변형 기능 플래그를 사용하여 서비스의 다양한 구현을 다른 사용자에게 노출할 수 있습니다. 인터페이스는 IVariantServiceProvider<TService> 이 조합을 수행하는 방법을 제공합니다.

IVariantServiceProvider<IAlgorithm> algorithmServiceProvider;
...

IAlgorithm forecastAlgorithm = await algorithmServiceProvider.GetServiceAsync(cancellationToken); 

이전 코드에서 IVariantServiceProvider<IAlgorithm> 구현은 종속성 주입 컨테이너에서 IAlgorithm 구현을 검색합니다. 선택한 구현은 다음에 따라 달라집니다.

  • 서비스가 등록된 기능 플래그 IAlgorithm 입니다.
  • 해당 기능에 할당된 변형입니다.

구현은 애플리케이션에서 사용할 수 있도록 IFeatureManagementBuilder.WithVariantService<T>(string featureName)을 호출하여 제공되며, 이는 다음의 예제와 같습니다. 이 코드의 호출은 IVariantServiceProvider<IAlgorithm>를 서비스 컬렉션에서 사용할 수 있게 합니다.

services.AddFeatureManagement() 
        .WithVariantService<IAlgorithm>("ForecastAlgorithm");

와 같은 IAlgorithmadd 메서드를 통해 각 구현 services.AddSingleton<IAlgorithm, SomeImplementation>() 을 개별적으로 추가해야 합니다. IVariantServiceProvider가 사용하는 IAlgorithm의 구현은 ForecastAlgorithm 변형 기능 플래그에 따라 다릅니다. IAlgorithm의 구현이 서비스 컬렉션에 추가되지 않은 경우, IVariantServiceProvider<IAlgorithm>.GetServiceAsync()null 결과를 포함하는 태스크를 반환합니다.

{
    // The example variant feature flag
    "id": "ForecastAlgorithm",
    "enabled": true,
    "variants": [
        { 
            "Name": "AlgorithmBeta" 
        },
        ...
    ] 
}

Variant 서비스 별칭 속성

Variant 서비스 공급자는 구현의 타입 이름을 사용하여 할당된 변형을 일치시킵니다. variant 서비스가 VariantServiceAliasAttribute로 장식된 경우 구성에서 이 특성에 선언된 이름을 사용하여 해당 variant 서비스를 참조해야 합니다.

[VariantServiceAlias("Beta")]
public class AlgorithmBeta : IAlgorithm
{
    ...
}

원격 분석

기능 플래그 변경을 배포할 때 애플리케이션에 미치는 영향을 분석하는 것이 중요합니다. 예를 들어 다음과 같은 몇 가지 질문이 발생할 수 있습니다.

  • 플래그가 예상대로 활성화되고 비활성화되었습니까?
  • 대상 사용자가 예상대로 특정 기능에 액세스하고 있나요?
  • 특정 사용자에게 어떤 변형이 표시되나요?

기능 플래그 평가 이벤트의 배출 및 분석은 이러한 유형의 질문에 답변하는 데 도움이 될 수 있습니다. .NET 기능 관리 라이브러리는 System.Diagnostics.Activity API를 사용하여 기능 플래그 평가 중에 추적 텔레메트리를 생성합니다.

원격 분석 활성화

기본적으로 기능 플래그에는 원격 분석이 내보내지지 않습니다. 지정된 기능 플래그에 대한 원격 분석을 게시하려면 플래그가 원격 분석 배출을 위해 활성화되었음을 선언해야 합니다.

appsettings.json에 정의된 기능 플래그의 경우, telemetry 속성을 사용하여 원격 분석을 활성화할 수 있습니다.

{
    "feature_management": {
        "feature_flags": [
            {
                "id": "MyFeatureFlag",
                "enabled": true,
                "telemetry": {
                    "enabled": true
                }
            }
        ]
    }
}

appsettings.json 파일의 이전 코드는 원격 분석에 사용하도록 설정된 기능 MyFeatureFlag 플래그를 정의합니다. telemetry 개체가 enabledtrue로 설정하여 원격 분석 상태가 표시됩니다. 플래그에 대한 원격 분석을 게시하려면 enabled 속성의 값이 true여야 합니다.

기능 플래그의 telemetry 섹션에는 다음과 같은 속성이 있습니다.

속성 설명
enabled 기능 플래그에 대한 원격 측정 정보를 게시할지 여부를 지정하는 부울 값입니다.
metadata 기능 플래그에 대한 사용자 지정 메타데이터를 평가 이벤트에 연결하는 데 사용할 수 있는 사전으로 모델링된 키-값 쌍의 컬렉션입니다.

사용자 지정 원격 분석 게시

기능 관리자에는 이름이 ActivitySource고유한 Microsoft.FeatureManagement 인스턴스가 있습니다. 기능 플래그에 대해 원격 분석을 사용하는 경우:

  • 기능 플래그 평가가 시작되면 기능 관리자는 인스턴스 Activity를 시작합니다.
  • 기능 플래그 평가가 완료되면 기능 관리자는 현재 활동에 명명된 ActivityEventFeatureFlag 인스턴스를 추가합니다.

이벤트에는 FeatureFlag 기능 플래그 평가에 대한 정보가 포함된 태그가 있습니다. 태그는 FeatureEvaluationEvent 스키마에 정의된 필드를 사용합니다.

참고

기능 플래그의 속성에 telemetry.metadata 지정된 모든 키-값 쌍도 태그에 포함됩니다.

사용자 지정 원격 분석 게시를 사용하도록 설정하려면 ActivityListener 인스턴스를 만들고 Microsoft.FeatureManagement 활동 원본을 수신 대기할 수 있습니다. 다음 코드에서는 기능 관리 활동 원본을 수신 대기하고 기능이 평가될 때 콜백을 추가하는 방법을 보여 있습니다.

ActivitySource.AddActivityListener(new ActivityListener()
{
    ShouldListenTo = (activitySource) => activitySource.Name == "Microsoft.FeatureManagement",
    Sample = (ref ActivityCreationOptions<ActivityContext> options) => ActivitySamplingResult.AllData,
    ActivityStopped = (activity) =>
    {
        ActivityEvent? evaluationEvent = activity.Events.FirstOrDefault((activityEvent) => activityEvent.Name == "FeatureFlag");

        if (evaluationEvent.HasValue && evaluationEvent.Value.Tags.Any())
        {
            // Do something.
        }
    }
});

자세한 내용은 분산 추적 수집을 참조하세요.

Application Insights 원격 분석

Microsoft.FeatureManagement.Telemetry.ApplicationInsights 패키지는 기능 플래그 평가 데이터를 Application Insights로 보내는 기본 제공된 원격 분석 게시자를 제공합니다. 또한 이 패키지는 모든 이벤트를 자동으로 TargetingId로 태그 지정하여 이벤트를 플래그 평가에 연결할 수 있는 원격 분석 이니셜라이저를 제공합니다. 이 기능을 활용하려면 패키지에 대한 참조를 추가하고 Application Insights 원격 분석을 등록합니다. 다음 코드는 예제를 제공합니다.

builder.services
    .AddFeatureManagement()
    .AddApplicationInsightsTelemetry();

참고

Application Insights 원격 분석이 예상대로 작동하는지 확인하려면 클래스를 TargetingHttpContextMiddleware 사용해야 합니다.

현재 작업에서 대상 지정 컨텍스트의 지속성을 사용하도록 설정하려면 클래스를 TargetingHttpContextMiddleware 사용할 수 있습니다.

app.UseMiddleware<TargetingHttpContextMiddleware>();

해당 사용의 예제는 VariantAndTelemetryDemo 예제를 참조하세요.

필수 요소

Microsoft.FeatureManagement.Telemetry.ApplicationInsights 패키지에서 제공하는 원격 분석 게시자를 사용하려면, Application Insights를 설정하고 애플리케이션 서비스로 등록해야 합니다. 샘플 코드는 VariantAndTelemetryDemo 예제 애플리케이션을 참조하세요.

캐싱

기능 상태는 IConfiguration 시스템에서 제공됩니다. 구성 공급자는 캐싱 및 동적 업데이트를 처리해야 합니다. 기능 관리자는 기능의 사용 여부를 평가할 때마다 기능 상태의 최신 값을 요청 IConfiguration 합니다.

스냅샷

일부 시나리오에서는 요청 수명 동안 기능의 상태가 일관성을 유지해야 합니다. 요청 중에 가져온 원본이 업데이트되는 경우 IVariantFeatureManager 표준 IConfiguration 구현에서 반환된 값이 변경됩니다.

를 사용하여 IVariantFeatureManagerSnapshot이 동작을 방지할 수 있습니다. 동일한 방법으로 IVariantFeatureManagerSnapshot를 검색할 수 있습니다 IVariantFeatureManager. IVariantFeatureManagerSnapshot 는 인터페이스를 IVariantFeatureManager 구현하지만 IVariantFeatureManagerSnapshot 요청 중에 기능의 첫 번째 평가 상태를 캐시합니다. 기능의 수명 동안 해당 상태를 반환합니다.

사용자 지정 기능 공급자

사용자 지정 기능 공급자를 구현할 때 데이터베이스 또는 기능 관리 서비스와 같은 원본에서 기능 플래그를 가져올 수 있습니다. 기본 기능 공급자는 .NET Core 구성 시스템에서 기능 플래그를 가져옵니다. 이 시스템은 appsettings.json 파일 또는 Azure App Configuration과 같은 구성 공급자에서 기능을 정의하기 위한 지원을 제공합니다. 기능 정의를 읽는 위치를 제어하도록 이 동작을 사용자 지정할 수 있습니다.

기능 정의의 로드를 사용자 지정하려면 인터페이스를 IFeatureDefinitionProvider 구현해야 합니다.

public interface IFeatureDefinitionProvider
{
    Task<FeatureDefinition> GetFeatureDefinitionAsync(string featureName);

    IAsyncEnumerable<FeatureDefinition> GetAllFeatureDefinitionsAsync();
}

구현 IFeatureDefinitionProvider을 사용하려면 기능 관리를 추가하기 전에 서비스 컬렉션에 추가해야 합니다. 다음 예에서는 InMemoryFeatureDefinitionProvider라는 IFeatureDefinitionProvider 구현을 추가합니다.

services.AddSingleton<IFeatureDefinitionProvider, InMemoryFeatureDefinitionProvider>()
        .AddFeatureManagement()

다음 단계

애플리케이션에서 기능 플래그를 사용하는 방법을 알아보려면 다음 빠른 시작을 참조하세요.

기능 필터를 사용하는 방법을 알아보려면 다음 자습서를 참조하세요.