Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Библиотека управления функциями .NET предоставляет способ разработки и предоставления функциональных возможностей приложений на основе флагов компонентов. При разработке новой функции многие приложения имеют особые требования, например, когда эта функция должна быть включена и в каких условиях. Эта библиотека предоставляет способ определения этих связей. Он также интегрируется с общими шаблонами кода .NET для предоставления этих функций.
Флаги функций позволяют приложениям .NET и ASP.NET Core включать или отключать функции динамически. Флаги функций можно использовать в основных случаях использования, таких как условные операторы. Вы также можете использовать флаги функций в более сложных сценариях, таких как условное добавление маршрутов или фильтров модель–представление–контроллер (MVC). Флаги компонентов основаны на системе конфигурации .NET Core. Любой поставщик конфигурации .NET Core может выступать в качестве магистрали флагов компонентов.
Ниже приведены некоторые преимущества использования библиотеки управления функциями .NET.
- В нем используются общие соглашения для управления функциями.
- Он имеет низкий барьер для входа:
- Он построен на интерфейсе
IConfiguration. - Он поддерживает настройку флага функции для JSON-файлов.
- Он построен на интерфейсе
- Он предоставляет управление временем существования флага функций.
- Значения конфигурации могут изменяться в режиме реального времени.
- Флаги функций могут быть согласованы по всему запросу.
- Он охватывает основные сложные сценарии, предлагая поддержку следующих возможностей:
- Включение и отключение функций с помощью декларативного файла конфигурации
- Представление различных вариантов функции различным пользователям
- Динамическое вычисление состояния функции на основе вызова сервера
- Он предоставляет расширения API для платформы ASP.NET Core и MVC в следующих областях:
- Маршрутизация
- Фильтры
- Атрибуты действия
Библиотека управления функциями .NET открытый код. Дополнительные сведения см. в репозитории FeatureManagement-Dotnet GitHub.
Флаги функций
Флаги компонентов можно включить или отключить. Состояние флага можно сделать условным с помощью фильтров компонентов.
Фильтры функций
Фильтры функций определяют сценарий, в котором должна быть включена функция. Чтобы оценить состояние функции, производится обход списка её фильтров до тех пор, пока один из фильтров не определит, что функция включена. На этом этапе обход по фильтрам компонентов останавливается. Если фильтр компонентов не указывает, что эта функция должна быть включена, считается отключенной.
Например, предположим, что вы разрабатываете фильтр функций браузера Microsoft Edge. Если HTTP-запрос поступает из Microsoft Edge, фильтр функций активирует любые функции, к которым он подключён.
Конфигурация флага компонента
Система конфигурации .NET Core используется для определения состояния флагов компонентов. Основой этой системы является IConfiguration интерфейс. Любой поставщик IConfiguration можно использовать в качестве поставщика состояния компонента для библиотеки флагов компонентов. Эта система поддерживает сценарии, начиная от файла конфигурации appsettings.json до Azure App Configuration.
Объявление флага функциональности
Библиотека управления функциями поддерживает файл конфигурации appsettings.json в качестве источника флага компонентов, так как это поставщик системы .NET Core IConfiguration . Флаги функций объявляются с помощью Microsoft Feature Management schema. Эта схема не зависит от языка и поддерживается во всех библиотеках управления функциями Майкрософт.
Код в следующем примере объявляет флаги компонентов в 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"
}
}
]
}
}
]
}
}
Раздел feature_management документа JSON используется по соглашению для загрузки параметров флага компонента. В этом разделе необходимо перечислить объекты флага компонентов в массиве feature_flags . В этом коде перечислены три флага компонента. У каждого объекта флага компонента есть id свойство и enabled свойство.
- Значением
idявляется имя, которое вы используете для идентификации и ссылки на флаг компонента. - Свойство
enabledуказывает состояние включенного флага компонента.
Функция отключается, если enabled является false. Если enabled это trueтак, состояние функции зависит от 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, чтобы функция была включена.
requirement_type
All изменяет способ обхода фильтров:
- Если фильтры не указаны, функция отключена.
- Если перечислены фильтры, они последовательно проверяются до тех пор, пока условия одного из них не укажут, что функция должна быть отключена. Если фильтр не указывает, что функция должна быть отключена, она считается включенной.
{
"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 процентов пользователей в течение указанного периода времени.
Обработка нескольких источников конфигурации
Начиная с версии 4.3.0, вы можете отказаться от пользовательского объединения флагов функций схемы Майкрософт (раздел feature_management ). Когда идентификатор флага компонента отображается в нескольких источниках конфигурации, экземпляр встроенного 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_management, так и в разделе FeatureManagement, будет принято объявление из раздела feature_management.
Потребление
В базовой реализации управление функциями проверяет, включен ли флаг компонента. Затем он выполняет действия на основе результата. Эта проверка выполняется с помощью IsEnabledAsync метода IVariantFeatureManager.
…
IVariantFeatureManager featureManager;
…
if (await featureManager.IsEnabledAsync("FeatureX"))
{
// Do something.
}
Регистрация сервиса
Управление функциями зависит от внедрения зависимостей .NET Core. Как показано в следующем коде, можно использовать стандартные соглашения для регистрации служб управления функциями:
using Microsoft.FeatureManagement;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddFeatureManagement();
}
}
По умолчанию менеджер функций извлекает конфигурацию флага функции из раздела feature_management или FeatureManagement данных конфигурации .NET Core. Если ни раздел не существует, конфигурация считается пустой.
Примечание.
Можно также указать, что конфигурация флага компонента должна быть получена из другого раздела конфигурации, передав раздел в 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 для включения распространенных сценариев флагов функций в веб-приложениях. Эти возможности доступны, ссылаясь на пакет NuGet Microsoft.FeatureManagement.AspNetCore .
Контроллеры и действия
Для выполнения контроллера и действий MVC может потребоваться включить определенную функцию или один из всех списков функций. Это требование можно выполнить с помощью FeatureGateAttribute объекта. Класс FeatureGateAttribute определяется в Microsoft.FeatureManagement.Mvc пространстве имен.
[FeatureGate("FeatureX")]
public class HomeController : Controller
{
…
}
В предыдущем примере HomeController класс управляется FeatureX.
HomeController действия могут выполняться только в том случае, если FeatureX функция включена.
[FeatureGate("FeatureX")]
public IActionResult Index()
{
return View();
}
В предыдущем примере действие MVC может выполняться только в том случае, Index если эта функция включена 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>
Примечание.
- Если указать вариант, следует указать только одну функцию.
- Если указать несколько вариантов и задать значение
Andдляrequirement, возникает ошибка. Невозможно назначить несколько вариантов.
Для <feature> тега требуется вспомогательный элемент тега. Чтобы использовать тег, добавьте вспомогательный тег управления функциями в файл _ViewImports.cshtml .
@addTagHelper *, Microsoft.FeatureManagement.AspNetCore
Фильтры MVC
Фильтры действий MVC можно настроить условно на основе состояния компонента. Чтобы настроить эти фильтры, зарегистрируйте их с учетом функционала. Конвейер управления функциями поддерживает асинхронные фильтры действий MVC, реализующие IAsyncActionFilter интерфейс.
services.AddMvc(o =>
{
o.Filters.AddForFeature<SomeMvcFilter>("FeatureX");
});
Предыдущий код регистрирует фильтр MVC с именем SomeMvcFilter. Этот фильтр активируется только в конвейере MVC, если FeatureX включен.
Страницы Razor
Для запуска страниц Razor MVC может потребоваться включить определенную функцию или один из всех списков функций. Это требование можно добавить с помощью FeatureGateAttribute объекта. Класс FeatureGateAttribute определяется в Microsoft.FeatureManagement.Mvc пространстве имен.
[FeatureGate("FeatureX")]
public class IndexModel : PageModel
{
public void OnGet()
{
}
}
Предыдущий код настраивает страницу Razor, для которой требуется включить FeatureX. Если функция не включена, страница создает результат HTTP 404 (NotFound).
При использовании FeatureGateAttribute объекта на страницах Razor необходимо поместить FeatureGateAttribute в тип обработчика страниц. Его нельзя поместить в отдельные методы обработчика.
Сборка приложений
Вы можете использовать библиотеку управления функциями для добавления ветвей приложений и ПО промежуточного слоя, которые выполняются условно на основе состояния компонента.
app.UseMiddlewareForFeature<ThirdPartyMiddleware>("FeatureX");
В приведенном выше коде приложение добавляет компонент ПО промежуточного слоя, который отображается в конвейере запросов только в том случае, если FeatureX эта функция включена. Если функция включена или отключена во время выполнения, конвейер ПО промежуточного слоя может быть динамически изменен.
Как показано в следующем коде, эта функция создает более универсальную возможность для ветвления всего приложения на основе функции.
app.UseForFeature(featureName, appBuilder =>
{
appBuilder.UseMiddleware<T>();
});
Реализация фильтра функций
Создание фильтра функций позволяет включить функции на основе заданных критериев. Чтобы реализовать фильтр компонентов, необходимо реализовать IFeatureFilter интерфейс.
IFeatureFilter имеет один метод с именем EvaluateAsync. Если компонент указывает, что его можно включить для фильтра компонентов, EvaluateAsync вызывается метод. Если EvaluateAsync возвращает true, то функция должна быть включена.
В следующем коде показано, как добавить пользовательский фильтр функций под названием MyCriteriaFilter.
services.AddFeatureManagement()
.AddFeatureFilter<MyCriteriaFilter>();
Вы можете зарегистрировать фильтр функции, вызвав AddFeatureFilter<T> в реализации IFeatureManagementBuilder, которую возвращает AddFeatureManagement. Фильтр компонентов имеет доступ к службам в коллекции служб, используемой для добавления флагов компонентов. Для получения этих служб можно использовать внедрение зависимостей.
Примечание.
При указании фильтров в настройках флагов функций (например, appsettings.json), следует опустить часть имени типа Filter. Дополнительные сведения см. в разделе "Атрибут псевдонима фильтра" далее в этой статье.
Параметризованные фильтры компонентов
Некоторые фильтры функций требуют параметров для оценки того, следует ли включить функцию. Например, фильтр функций браузера может включить функцию для определенного набора браузеров. Возможно, вы хотите включить функцию в браузерах Microsoft Edge и Chrome, но не в Firefox.
Чтобы реализовать эту фильтрацию, можно разработать фильтр функций для принятия параметров. Эти параметры указываются в конфигурации компонентов. В коде доступ к ним осуществляется через параметр FeatureFilterEvaluationContextIFeatureFilter.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; }
}
Класс FeatureFilterEvaluationContext имеет свойство с именем Parameters. Параметры этого свойства представляют необработанную конфигурацию, которую фильтр компонентов может использовать при оценке необходимости включения функции. В примере фильтра функций браузера фильтр может использовать 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 удалён, если он имеется. Например, в конфигурации следует называть MyCriteriaFilter как MyCriteria.
{
"id": "MyFeature",
"enabled": true,
"conditions": {
"client_filters": [
{
"name": "MyCriteria"
}
]
}
}
Это имя можно переопределить с помощью FilterAliasAttribute класса. Чтобы объявить имя, используемое в конфигурации для ссылки на фильтр компонентов в флаге компонента, можно указать фильтр компонентов с помощью этого атрибута.
Отсутствующие фильтры функций
Предположим, что вы настраиваете функцию для определенного фильтра компонентов. Если этот фильтр компонентов не зарегистрирован, при оценке компонента возникает исключение. Как показано в следующем коде, можно отключить исключение с помощью параметров управления функциями.
services.Configure<FeatureManagementOptions>(options =>
{
options.IgnoreMissingFeatureFilters = true;
});
Используйте HttpContext
Фильтры функций могут оценить, следует ли включить функцию на основе свойств HTTP-запроса. Эта проверка выполняется путем проверки контекста HTTP. Как показано в следующем коде, фильтр функций может получить ссылку на контекст HTTP с помощью внедрения зависимостей для получения реализации IHttpContextAccessor.
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();
…
}
Для продвинутых пользователей:IHttpContextAccessor и HttpContext не следует использовать в компонентах Razor приложений Blazor на стороне сервера.
Рекомендуемый подход к передаче контекста HTTP в приложениях Blazor заключается в копировании данных в службу с областью действия. Для приложений Blazor следует использовать AddScopedFeatureManagement для регистрации служб управления функциями. Дополнительные сведения см. в разделе "Управление функциями с определенной областью действия", выше в этой статье.
Предоставление контекста для оценки компонентов
В консольных приложениях отсутствует амбентный контекст, который могли бы использовать фильтры функций для проверки необходимости включения функции. В этом случае приложениям необходимо предоставить объект, представляющий контекст системы управления функциями для использования фильтрами компонентов. Вы можете использовать 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.
Использование контекстных и не контекстных фильтров с одинаковым псевдонимом
Фильтры, реализующие IFeatureFilter и IContextualFeatureFilter, могут совместно использовать один и тот же псевдоним. В частности, можно использовать один псевдоним фильтра, который разделяют не более чем нулевая или одна реализация, а также ноль или IFeatureFilterNIContextualFeatureFilter<ContextType> реализаций, если существует не более одного применимого фильтра для ContextType.
Чтобы понять процесс выбора фильтра, когда контекстные и не контекстные фильтры того же имени регистрируются в приложении, рассмотрим следующий пример.
Три фильтра совместно используют SharedFilterName псевдоним:
- Не контекстный фильтр, называемый
FilterA - Контекстный фильтр
FilterB, принимающий контекстTypeB - Контекстный фильтр
FilterC, который принимает контекстTypeC.
Флаг функции под названием MyFeature использует фильтр функций SharedFilterName в своей конфигурации.
Если регистрируются все три фильтра:
- При вызове
IsEnabledAsync("MyFeature"), фильтрFilterAиспользуется для оценки флага признака. - При вызове
IsEnabledAsync("MyFeature", context):- Если тип
context— этоTypeB, используетсяFilterB. - Если тип
contextявляетсяTypeC, используетсяFilterC. - Если тип
contextявляетсяTypeF, используетсяFilterA.
- Если тип
Встроенные фильтры функций
Существует несколько фильтров для функций, которые поставляются с пакетом Microsoft.FeatureManagement: PercentageFilter, TimeWindowFilter, ContextualTargetingFilter и TargetingFilter. Все фильтры, кроме того TargetingFilter , добавляются автоматически при использовании AddFeatureManagement метода для регистрации управления функциями.
TargetingFilter добавляется с помощью WithTargeting метода. Дополнительные сведения см. в статье "Назначение" далее в этой статье.
Каждый из встроенных фильтров функций имеет собственные параметры. В следующих разделах описаны эти фильтры функций и приведены примеры.
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 параметр для указания правила повторения.
Примечание.
Чтобы использовать повторение, необходимо указать Start и End значения. При повторении часть даты значения 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указывают, сколько времени повторяется шаблон повторения.
Шаблон повторения
Существует два возможных типа шаблонов повторения: Daily и Weekly. Например, период времени может повторяться каждый день, каждые три дня, каждый понедельник или каждую другую пятницу.
В зависимости от типа некоторые поля Pattern параметров являются обязательными, необязательными или игнорируются.
DailyМодель ежедневного повторения вызывает повторение временного интервала с учетом указанного количества дней между каждым случаем.
Свойство С сортировкой по релевантности Описание TypeОбязательное поле Тип шаблона повторения. Должен иметь значение Daily.IntervalНеобязательно Количество дней между каждым повторением. Значение по умолчанию — 1.WeeklyЕженедельный шаблон повторения приводит к повтору периода времени в один день или дни недели. Но можно указать количество недель между каждым набором повторений.
Свойство С сортировкой по релевантности Описание TypeОбязательное поле Тип шаблона повторения. Должен иметь значение Weekly.DaysOfWeekОбязательное поле Дни недели, на которые происходит событие. IntervalНеобязательно Количество недель между каждым набором событий. Значение по умолчанию — 1.FirstDayOfWeekНеобязательно День, используемый в качестве первого дня недели. Значение по умолчанию — Sunday.Пример ниже демонстрирует повторение временного интервала каждые вторые понедельник и вторник:
"Pattern": { "Type": "Weekly", "Interval": 2, "DaysOfWeek": ["Monday", "Tuesday"] }
Примечание.
Значение Start должно быть допустимым первым вхождением, которое соответствует шаблону повторения. Кроме того, длительность периода времени не может превышать частоту его возникновения. Например, 25-часовое окно времени не может повторяться каждый день.
Диапазон повторений
Существует три возможных типа диапазонов повторений: NoEnd, EndDateи Numbered.
NoEndДиапазон
NoEndприводит к тому, что повторение происходит на неопределенный срок.Свойство С сортировкой по релевантности Описание TypeОбязательное поле Тип диапазона повторений. Должен иметь значение NoEnd.EndDateДиапазон
EndDateприводит к возникновению периода времени в течение всех дней, которые соответствуют применимому шаблону до даты окончания.Свойство С сортировкой по релевантности Описание TypeОбязательное поле Тип диапазона повторений. Должен иметь значение EndDate.EndDateОбязательное поле Дата и время прекращения применения шаблона. Если время начала последнего вхождения начинается перед датой окончания, время окончания этого вхождения может превышать её. В следующем примере временное окно повторяется на каждый день до последнего появления 1 апреля 2024 года.
"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Обязательное поле Количество вхождений. В следующем примере временное окно повторяется в понедельник и вторник всего три раза, которое происходит в следующие даты:
- Понедельник, 1 апреля
- Вторник, 2 апреля
- Понедельник, 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 } }
Чтобы создать правило повторения, необходимо указать оба Pattern и Range параметры. Любой тип шаблона может работать с любым типом диапазона.
Дополнительно: смещение часового пояса 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.
Таргетинг
Таргетирование — это стратегия управления функциями, которую можно использовать для постепенного развертывания новых функций в базе пользователей. Стратегия основана на концепции целевой аудитории для набора пользователей, известных как целевая аудитория. Аудитория состоит из определенных пользователей, групп, исключенных пользователей и групп, и указанного процента всей базы пользователей. Группы, включенные в аудиторию, могут быть разбиты дальше на проценты их общих членов.
Ниже приведен пример прогрессивного развертывания для новой функции с именем Beta:
- Отдельные пользователи Джефф и Алисия получают доступ к бета-функции.
- Другой пользователь, Марк, просит принять участие и включен.
- Двадцать процентов пользователей в группе Ring1 включены в бета-версию.
- Число пользователей Ring1 увеличено до 100 процентов.
- Пять процентов пользовательской базы включены в бета-версию функции.
- Процент развертывания увеличивается до 100 процентов для полного развертывания функции.
Библиотека поддерживает эту стратегию развертывания функции с помощью встроенного фильтра компонентов Microsoft.Targeting .
Таргетинг в веб-приложении
Пример веб-приложения, использующего фильтр функций целевого объекта, см. в примере проекта FeatureFlagDemo .
Чтобы начать использование TargetingFilter в приложении, необходимо добавить его в коллекцию служб приложения так же, как и любой другой фильтр функций. В отличие от других встроенных фильтров, TargetingFilter требуется добавить другую службу в коллекцию служб приложения. Эта служба является реализацией ITargetingContextAccessor.
Библиотека Microsoft.FeatureManagement.AspNetCore предоставляет реализацию ITargetingContextAccessor, которая извлекает целевые сведения из значения запросаHttpContext. При настройке таргетинга можно использовать контекст доступа по умолчанию, используя негласную WithTargeting перегрузку на IFeatureManagementBuilder.
Чтобы зарегистрировать метод доступа контекста по умолчанию и TargetingFilter, вызовите WithTargeting на IFeatureManagementBuilder.
services.AddFeatureManagement()
.WithTargeting();
Вы также можете зарегистрировать настраиваемую реализацию для ITargetingContextAccessor вызова и TargetingFilter вызова WithTargeting<T>. Следующий код настраивает функциональное управление в веб-приложении для использования TargetingFilter с реализацией ITargetingContextAccessor под названием ExampleTargetingContextAccessor.
services.AddFeatureManagement()
.WithTargeting<ExampleTargetingContextAccessor>();
ITargetingContextAccessor
Для использования TargetingFilter в веб-приложении требуется реализация ITargetingContextAccessor . Причина этого требования заключается в том, что контекстные сведения, такие как сведения о пользователе, необходимы для целевых вычислений. Эти сведения хранятся в экземплярах TargetingContext класса. Различные приложения извлекают эти сведения из разных мест, например контекст HTTP запроса или базу данных.
Для примера, который извлекает сведения о контексте целевой аудитории из HTTP-контекста приложения, см. DefaultHttpTargetingContextAccessor в пакете Microsoft.FeatureManagement.AspNetCore. Он извлекает следующие сведения:
- Ориентация на сведения из
HttpContext.Userсвойства -
UserIdсведения изIdentity.Nameполя -
Groupsсведения из утверждений типаRole
Эта реализация зависит от использования IHttpContextAccessor. Дополнительные сведения см. в IHttpContextAccessorразделе "Использование HttpContext" ранее в этой статье.
Ориентирование в консольном приложении
Фильтр целевых объектов зависит от контекста целевого объекта, чтобы оценить, следует ли включить функцию. Этот контекст целевого объекта содержит такие сведения, как пользователь, который оценивается, и группы, к которым принадлежит пользователь. В консольных приложениях обычно нет контекста окружающей среды для передачи этой информации в целевой фильтр. В результате при вызове FeatureManager.IsEnabledAsyncнеобходимо передать его непосредственно. Этот тип контекста поддерживается с помощью ContextualTargetingFilter. Приложения, которые должны отправлять контекст целевого объекта диспетчеру функций, следует использовать ContextualTargetingFilter вместо TargetingFilter.
Поскольку ContextualTargetingFilter реализует IContextualTargetingFilter<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"
]
}
}
Приведенный выше код включает функцию для пользователей с именем Jeff и Alicia. Эта функция также включена для пользователей в группе с именем 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; }
}
Извлечение вариантов
Для каждой GetVariantAsync функции можно получить вариант с помощью IVariantFeatureManager метода интерфейса.
…
IVariantFeatureManager featureManager;
…
Variant variant = await featureManager.GetVariantAsync("MyVariantFeatureFlag", CancellationToken.None);
IConfigurationSection variantConfiguration = variant.Configuration;
// Do something with the resulting variant and its configuration.
После получения варианта можно использовать его конфигурацию непосредственно в качестве реализации IConfigurationSection из свойства Configuration варианта. Другим вариантом является привязка конфигурации к объекту с помощью шаблона привязки конфигурации .NET.
IConfigurationSection variantConfiguration = variant.Configuration;
MyFeatureSettings settings = new MyFeatureSettings();
variantConfiguration.Bind(settings);
Возвращаемый вариант зависит от пользователя, который оценивается. Вы можете получить сведения о пользователе из экземпляра TargetingContext. Этот контекст можно передать при вызове GetVariantAsync. Или его можно автоматически извлечь из реализации ITargetingContextAccessor , если она зарегистрирована.
Объявление флага функции Variant
По сравнению с стандартными флагами функций флаги вариантов имеют два дополнительных свойства: 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, свойство возвращаемого варианта 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, group, и percentile в этом порядке, чтобы назначить вариант. В предыдущем примере указанный вариант Bigназначается пользователю в следующих случаях:
- Оцениваемый пользователь называется
Marsha. - Пользователь находится в
Ring1группе. - Пользователь попадает в диапазон от нулевого до десятого процентиля.
Если ни одно из этих распределений не подходит, вариант default_when_enabled назначается пользователю. В этом примере этот вариант — Small.
Логика выделения аналогична логике, используемой для фильтра функций Microsoft.Targeting . Но существуют некоторые параметры, которые присутствуют в таргетинге, но отсутствуют в распределении, и наоборот. Результаты целевого и распределения не связаны.
Примечание.
Чтобы выделить варианты функций, необходимо зарегистрировать ITargetingContextAccessor путем вызова метода WithTargeting<T>.
Переопределите состояние с помощью варианта
Варианты можно использовать для переопределения состояния включенного флага компонента. При использовании этой функции можно расширить оценку флага функции. Во время вызова IsEnabledAsync для флага с вариантами менеджер функций проверяет, настроен ли назначенный текущему пользователю вариант на переопределение результата.
Переопределение можно реализовать с использованием свойства variant, которое является необязательным status_override. Это свойство может иметь следующие значения:
-
None: вариант не влияет на то, включен или отключен флаг. По умолчанию устанавливается значениеNone. -
Enabled: при выборе варианта флаг компонента оценивается как включенный. -
Disabled: при выборе варианта флаг компонента оценивается как отключенный.
Невозможно переопределить функцию со состоянием enabledfalse.
Если вы используете флаг функции с двоичными вариантами, status_override это свойство может оказаться полезным. Вы можете продолжать использовать ТАКИЕ API, как IsEnabledAsync и FeatureGateAttribute в приложении. Но вы также можете использовать функции, доступные в вариантах, такие как распределение процентилей и использование начального значения для процентных расчетов.
{
"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которым зарегистрирована служба. - Выделенный вариант для этой функции.
Реализация IVariantServiceProvider<T> становится доступной для приложения путем вызова IFeatureManagementBuilder.WithVariantService<T>(string featureName), как показано в следующем примере. В этом коде вызов делает IVariantServiceProvider<IAlgorithm> доступным в коллекции служб.
services.AddFeatureManagement()
.WithVariantService<IAlgorithm>("ForecastAlgorithm");
Необходимо добавить каждую реализацию IAlgorithm отдельно с помощью метода добавления, например services.AddSingleton<IAlgorithm, SomeImplementation>(). Реализация IAlgorithm этого IVariantServiceProvider метода зависит от флага ForecastAlgorithm функции variant. Если реализация IAlgorithm не добавлена в коллекцию служб, IVariantServiceProvider<IAlgorithm>.GetServiceAsync() возвращает задачу с результатом null .
{
// The example variant feature flag
"id": "ForecastAlgorithm",
"enabled": true,
"variants": [
{
"Name": "AlgorithmBeta"
},
...
]
}
Атрибут псевдонима службы Variant
Поставщик служб variant использует имена типов реализаций для сопоставления выделенного варианта. Если служба вариантов помечена VariantServiceAliasAttribute, имя, объявленное в этом атрибуте, должно использоваться в конфигурации для обозначения этой службы вариантов.
[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, который устанавливает enabled на true. Значение enabled свойства должно быть true для публикации телеметрии для флага.
Раздел telemetry флага компонента имеет следующие свойства:
| Свойство | Описание |
|---|---|
enabled |
Логическое значение, указывающее, следует ли публиковать данные телеметрии для флажка функции. |
metadata |
Коллекция объектов пар "ключ-значение", моделируемая как словарь, которую можно использовать для присоединения пользовательских метаданных о флаге функции к оценочным событиям. |
Публикация телеметрии, настроенной пользователем
Диспетчер функций имеет собственный ActivitySource экземпляр с именем Microsoft.FeatureManagement. Если для флага компонента включена телеметрия:
- При запуске оценки флага компонента диспетчер функций запускает экземпляр
Activity. - После завершения оценки флага функции менеджер функций добавляет
ActivityEventэкземпляр с именемFeatureFlagв текущую активность.
Событие 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. Пакет Microsoft.FeatureManagement.Telemetry.ApplicationInsights также предоставляет инициализатор телеметрии, который автоматически тегирует все события, 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. Вы можете настроить это поведение, чтобы управлять тем, откуда считываются определения функций.
Чтобы настроить загрузку определений компонентов, необходимо реализовать IFeatureDefinitionProvider интерфейс.
public interface IFeatureDefinitionProvider
{
Task<FeatureDefinition> GetFeatureDefinitionAsync(string featureName);
IAsyncEnumerable<FeatureDefinition> GetAllFeatureDefinitionsAsync();
}
Чтобы использовать реализацию IFeatureDefinitionProvider, перед добавлением управления функциями необходимо добавить его в коллекцию служб. В следующем примере добавляется реализация IFeatureDefinitionProvider именованных InMemoryFeatureDefinitionProvider.
services.AddSingleton<IFeatureDefinitionProvider, InMemoryFeatureDefinitionProvider>()
.AddFeatureManagement()
Следующие шаги
Чтобы узнать, как использовать флаги функций в приложениях, ознакомьтесь со следующими краткими руководствами.
Сведения об использовании фильтров функций см. в следующих руководствах.