Управление функциями .NET
Библиотека управления функциями .NET позволяет разрабатывать и предоставлять функциональные возможности приложений на основе флагов компонентов. После разработки новой функции многие приложения имеют особые требования, например, когда эта функция должна быть включена и в каких условиях. Эта библиотека предоставляет способ определения этих связей, а также интеграции с общими шаблонами кода .NET для предоставления этих функций.
Флаги функций позволяют приложениям .NET и ASP.NET Core включать или отключать функции динамически. Разработчики могут использовать флаги функций в простых случаях использования, таких как условные инструкции для более сложных сценариев, таких как условное добавление маршрутов или фильтров MVC. Флаги компонентов основаны на системе конфигурации .NET Core. Любой поставщик конфигурации .NET Core может выступать в качестве магистрали флагов компонентов.
Ниже приведены некоторые преимущества использования библиотеки управления функциями .NET.
Общее соглашение об управлении функциями
Низкий барьер к входу
- Построено на основе
IConfiguration
- Поддерживает настройку флага компонента JSON
- Построено на основе
Управление временем существования флага компонентов
- Значения конфигурации могут изменяться в режиме реального времени; Флаги функций могут быть согласованы по всему запросу
Простые и сложные сценарии
- Включение и отключение функций с помощью декларативного файла конфигурации
- Динамическое вычисление состояния функции на основе вызова сервера
Расширения API для платформы ASP.NET Core и MVC
- Маршрутизация
- Фильтры
- Атрибуты действия
Библиотека управления функциями .NET открытый код. Дополнительные сведения см. в репозитории GitHub.
Флаги компонентов
Флаги компонентов состоят из двух частей, имени и списка фильтров функций, которые используются для включения функции.
Фильтры компонентов
Фильтры функций определяют сценарий, в котором должна быть включена функция. Если функция оценивается для того, включена ли она или отключена, список фильтров функций проходит до тех пор, пока один из фильтров не решит, что эта функция должна быть включена. На этом этапе функция считается включенной и обхода через фильтры компонентов останавливается. Если фильтр компонентов не указывает, что эта функция должна быть включена, считается отключенной.
Например, можно создать фильтр функций браузера Microsoft Edge. Этот фильтр функций активирует все функции, к ним присоединенные, если HTTP-запрос поступает из Microsoft Edge.
Конфигурация флага компонента
Система конфигурации .NET Core используется для определения состояния флагов компонентов. Основой этой системы является IConfiguration
. Любой поставщик IConfiguration
можно использовать в качестве поставщика состояния компонента для библиотеки флагов компонентов. Эта система позволяет сценариям от appsettings.json до Конфигурация приложений Azure и многое другое.
Объявление флага компонента
Библиотека управления функциями поддерживает appsettings.json в качестве источника флага компонентов, так как это поставщик системы .NET Core IConfiguration
. Ниже приведен пример формата, используемого для настройки флагов компонентов в json-файле.
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
// Define feature flags in a json file
"FeatureManagement": {
"FeatureT": {
"EnabledFor": [
{
"Name": "AlwaysOn"
}
]
},
"FeatureU": {
"EnabledFor": []
},
"FeatureV": {
"EnabledFor": [
{
"Name": "TimeWindow",
"Parameters": {
"Start": "Wed, 01 May 2019 13:59:59 GMT",
"End": "Mon, 01 Jul 2019 00:00:00 GMT"
}
}
]
}
}
}
Раздел FeatureManagement
документа JSON используется по соглашению для загрузки параметров флага компонентов. В приведенном выше разделе мы видим три различных компонента. Функции определяют фильтры функций с помощью EnabledFor
свойства. В фильтрах FeatureT
функций для , мы видим AlwaysOn
. Этот фильтр функций встроенный, и если он указан, всегда будет включать эту функцию. Фильтр AlwaysOn
компонентов не требует какой-либо конфигурации, поэтому он имеет Name
только свойство. FeatureU
не имеет фильтров в своем EnabledFor
свойстве и поэтому никогда не будет включен. Все функции, использующие эту функцию, не будут доступны, пока фильтры функций остаются пустыми. Тем не менее, как только будет добавлен фильтр компонентов, который включает функцию, которую он может начать работать. FeatureV
указывает фильтр признаков с именем TimeWindow
. Это пример настраиваемого фильтра компонентов. Мы видим в примере, что фильтр имеет Parameters
свойство. Используется для настройки фильтра. В этом случае настроено время начала и окончания для активной функции.
Подробные схемы FeatureManagement
раздела можно найти здесь.
Дополнительно. Использование двоеточия ":" запрещено в именах флагов признаков.
Объявление "вкл./выкл."
В следующем фрагменте кода демонстрируется альтернативный способ определения функции, которая может использоваться для функций включено или выключение.
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
// Define feature flags in config file
"FeatureManagement": {
"FeatureT": true, // On feature
"FeatureX": false // Off feature
}
}
Тип требования
Свойство RequirementType
флага компонента используется для определения того, должны ли фильтры использовать Any
или All
логику при оценке состояния компонента. Если RequirementType
значение по умолчанию не указано, значение Any
по умолчанию .
Any
означает, что только один фильтр должен иметь значение true для включения функции.All
означает, что каждый фильтр должен иметь значение true для включения функции.
All
Изменение RequirementType
обхода. Во-первых, если фильтров нет, функция отключена. Затем фильтры функций проходят по одному из фильтров, пока один из фильтров не решит, что эта функция должна быть отключена. Если фильтр не указывает, что функция должна быть отключена, она считается включенной.
"FeatureW": {
"RequirementType": "All",
"EnabledFor": [
{
"Name": "TimeWindow",
"Parameters": {
"Start": "Mon, 01 May 2023 13:59:59 GMT",
"End": "Sat, 01 Jul 2023 00:00:00 GMT"
}
},
{
"Name": "Percentage",
"Parameters": {
"Value": "50"
}
}
]
}
В приведенном выше примере указывает значение RequirementType
All
, FeatureW
что означает, что все его фильтры должны иметь значение true, чтобы функция была включена. В этом случае функция включена для 50% пользователей в течение указанного периода времени.
Схема управления функциями Майкрософт
Библиотека управления функциями также поддерживает использование Microsoft Feature Management schema
флагов компонентов. Эта схема не зависит от языка и поддерживается всеми библиотеками управления функциями Майкрософт.
{
"feature_management": {
"feature_flags": [
{
"id": "FeatureT",
"enabled": true,
"conditions": {
"client_filters": [
{
"name": "Microsoft.TimeWindow",
"parameters": {
"Start": "Mon, 01 May 2023 13:59:59 GMT",
"End": "Sat, 01 Jul 2023 00:00:00 GMT"
}
}
]
}
}
]
}
}
Примечание.
Если раздел feature_management
можно найти в конфигурации, FeatureManagement
раздел игнорируется.
Библиотека управления функциями поддерживает 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": "Mon, 01 May 2023 13:59:59 GMT",
"End": "Sat, 01 July 2023 00:00:00 GMT"
}
}
]
}
}
]
}
}
Раздел feature_management
документа JSON используется по соглашению для загрузки параметров флага компонентов. Объекты флага компонентов должны быть перечислены в массиве feature_flags
feature_management
в разделе. В приведенном выше разделе мы видим, что мы предоставили три различных функции. Флаг компонента имеет id
и enabled
свойства. Это id
имя, используемое для идентификации и ссылки на флаг компонента. Свойство enabled
указывает состояние включенного флага компонента. Функция отключена, если enabled
имеет значение false. Если enabled
задано значение true, состояние функции зависит от conditions
значения. Если нетconditions
, функция включена. Если есть conditions
и они выполнены, функция включена. Если есть conditions
и они не выполнены, функция отключена. Свойство conditions
объявляет условия, используемые для динамического включения функции. Функции определяют фильтры функций в массиве client_filters
. FeatureV
указывает фильтр признаков с именем Microsoft.TimeWindow
. Это пример настраиваемого фильтра компонентов. Мы видим в примере, что фильтр имеет Parameters
свойство. Используется для настройки фильтра. В этом случае настроено время начала и окончания для активной функции.
Дополнительно. Использование двоеточия ":" запрещено в именах флагов признаков.
Тип требования
Свойство requirement_type
conditions
используется для определения того, должны ли фильтры использовать Any
или All
логику при оценке состояния компонента. Если requirement_type
значение по умолчанию не указано, значение Any
по умолчанию .
Any
означает, что только один фильтр должен иметь значение true для включения функции.All
означает, что каждый фильтр должен иметь значение true для включения функции.
All
Изменение requirement_type
обхода. Во-первых, если фильтр отсутствует, функция будет отключена. Если существуют фильтры, то фильтры функций проходят до тех пор, пока один из фильтров не решит, что эта функция должна быть отключена. Если фильтр не указывает, что компонент должен быть отключен, он будет считаться включенным.
{
"id": "FeatureW",
"enabled": true,
"conditions": {
"requirement_type": "All",
"client_filters": [
{
"name": "Microsoft.TimeWindow",
"parameters": {
"Start": "Mon, 01 May 2023 13:59:59 GMT",
"End": "Sat, 01 Jul 2023 00:00:00 GMT"
}
},
{
"name": "Microsoft.Percentage",
"parameters": {
"Value": "50"
}
}
]
}
}
В приведенном выше примере указывает значение requirement_type
All
, FeatureW
что означает, что все его фильтры должны иметь значение true, чтобы функция была включена. В этом случае функция будет включена для 50% пользователей в течение указанного периода времени.
Схема управления функциями .NET
В предыдущих версиях основная схема библиотеки управления функциями была основной .NET feature management schema
. Начиная с версии 4.0.0 новые функции, включая варианты и данные телеметрии, не будут поддерживаться для схемы управления функциями .NET.
Примечание.
Если флаг компонента, написанный с Microsoft Feature Management schema
помощью конфигурации, можно найти в конфигурации, любой флаг компонента, записанный с ним .NET feature management schema
, будет игнорироваться.
Потребление
Базовая форма управления функциями проверяет, включен ли флаг компонента, а затем выполняет действия на основе результата. Это делается с помощью IFeatureManager
IsEnabledAsync
метода.
…
IFeatureManager featureManager;
…
if (await featureManager.IsEnabledAsync("FeatureX"))
{
// Do something
}
Регистрация службы
Управление функциями зависит от внедрения зависимостей .NET Core. Мы можем зарегистрировать службы управления функциями с помощью стандартных соглашений.
using Microsoft.FeatureManagement;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddFeatureManagement();
}
}
По умолчанию диспетчер компонентов получает конфигурацию флага компонента из раздела "FeatureManagement" данных конфигурации .NET Core. Если раздел FeatureManagement не существует, конфигурация считается пустой.
Примечание.
Можно также указать, что конфигурация флага компонентов должна быть получена из другого раздела конфигурации, передав раздел в AddFeatureManagement
. В следующем примере диспетчер функций сообщает диспетчеру функций прочитать из другого раздела "MyFeatureFlags" вместо этого:
services.AddFeatureManagement(configuration.GetSection("MyFeatureFlags"));
Внедрение зависимостей
При использовании библиотеки управления функциями с MVC IFeatureManager
можно получить с помощью внедрения зависимостей.
public class HomeController : Controller
{
private readonly IFeatureManager _featureManager;
public HomeController(IFeatureManager featureManager)
{
_featureManager = featureManager;
}
}
Службы управления функциями с областью действия
Этот AddFeatureManagement
метод добавляет службы управления функциями в качестве одноэлементных в приложении, но существуют сценарии, в которых может потребоваться добавить службы управления функциями в качестве областных служб. Например, пользователи могут использовать фильтры функций, использующие службы с областью действия для контекстной информации. В этом случае AddScopedFeatureManagement
вместо этого следует использовать метод. Это гарантирует, что службы управления функциями, включая фильтры компонентов, добавляются в качестве служб с областью действия.
services.AddScopedFeatureManagement();
интеграция ASP.NET Core
Библиотека управления функциями предоставляет функциональные возможности в ASP.NET Core и MVC для включения распространенных сценариев флагов функций в веб-приложениях. Эти возможности доступны, ссылаясь на пакет NuGet Microsoft.FeatureManagement.AspNetCore .
Контроллеры и действия
Для выполнения контроллера и действий MVC может потребоваться включить определенную функцию или один из всех списков функций. Это можно сделать с помощью FeatureGateAttribute
элемента, который можно найти в Microsoft.FeatureManagement.Mvc
пространстве имен.
[FeatureGate("FeatureX")]
public class HomeController : Controller
{
…
}
Приведенный HomeController
выше элемент имеет значение FeatureX. Параметр FeatureX должен быть включен перед выполнением любого действия HomeController
, содержащегося в нем.
[FeatureGate("FeatureX")]
public IActionResult Index()
{
return View();
}
Для Index
включения действия MVC выше требуется включить FeatureX, прежде чем его можно будет выполнить.
Обработка отключенных действий
Если контроллер или действие MVC заблокированы, так как ни одна из указанных функций не включена, будет вызываться зарегистрированный IDisabledFeaturesHandler
контроллер или действие. По умолчанию регистрируется минималистичный обработчик, который возвращает HTTP 404. Это можно переопределить с помощью IFeatureManagementBuilder
флагов функций регистрации.
public interface IDisabledFeaturesHandler
{
Task HandleDisabledFeature(IEnumerable<string> features, ActionExecutingContext context);
}
Представления
В тегах представлений <feature>
MVC можно использовать для условной отрисовки содержимого в зависимости от того, включена ли функция.
<feature name="FeatureX">
<p>This can only be seen if 'FeatureX' is enabled.</p>
</feature>
Вы также можете отменить вспомогательное вычисление тега для отображения содержимого при отключении компонента или набора компонентов. negate="true"
Установив в приведенном ниже примере, содержимое отображается только при FeatureX
отключении.
<feature negate="true" name="FeatureX">
<p>This can only be seen if 'FeatureX' is disabled.</p>
</feature>
Тег <feature>
может ссылаться на несколько функций, указав разделенный запятыми список функций в атрибуте name
.
<feature name="FeatureX,FeatureY">
<p>This can only be seen if 'FeatureX' and 'FeatureY' are enabled.</p>
</feature>
По умолчанию все перечисленные компоненты должны быть включены для отрисовки тега компонента. Это поведение можно переопределить, добавив requirement
атрибут, как показано в приведенном ниже примере.
<feature name="FeatureX,FeatureY" requirement="Any">
<p>This can only be seen if either 'FeatureX' or 'FeatureY' or both are enabled.</p>
</feature>
В тегах представлений <feature>
MVC можно использовать для условной отрисовки содержимого в зависимости от того, включена ли функция или назначен конкретный вариант функции. Дополнительные сведения см. в разделе "Варианты ".
<feature name="FeatureX">
<p>This can only be seen if 'FeatureX' is enabled.</p>
</feature>
<feature name="FeatureX" variant="Alpha">
<p>This can only be seen if variant 'Alpha' of 'FeatureX' is assigned.</p>
</feature>
Вы также можете отменить вспомогательное вычисление тега для отображения содержимого при отключении компонента или набора компонентов. negate="true"
Установив в приведенном ниже примере, содержимое отображается только при FeatureX
отключении.
<feature negate="true" name="FeatureX">
<p>This can only be seen if 'FeatureX' is disabled.</p>
</feature>
<feature negate="true" name="FeatureX" variant="Alpha">
<p>This can only be seen if variant 'Alpha' of 'FeatureX' isn't assigned.</p>
</feature>
Тег <feature>
может ссылаться на несколько функций и вариантов, указав разделенный запятыми список функций и вариантов в атрибуте name
/variant
.
<feature name="FeatureX,FeatureY">
<p>This can only be seen if 'FeatureX' and 'FeatureY' are enabled.</p>
</feature>
<feature name="FeatureX" variant="Alpha,Beta">
<p>This can only be seen if variant 'Alpha' or 'Beta' of 'FeatureX' is assigned.</p>
</feature>
Примечание.
Если variant
задано, необходимо указать только одну функцию.
По умолчанию все перечисленные компоненты должны быть включены для отрисовки тега компонента. Это поведение можно переопределить, добавив requirement
атрибут, как показано в приведенном ниже примере.
Примечание.
requirement
And
Если используется в сочетании с variant
ошибкой, возникает ошибка, так как нельзя назначать несколько вариантов.
<feature name="FeatureX,FeatureY" requirement="Any">
<p>This can only be seen if either 'FeatureX' or 'FeatureY' or both are enabled.</p>
</feature>
Для <feature>
тега требуется вспомогательный элемент тега. Это можно сделать, добавив вспомогательный тег управления функциями в файл ViewImports.cshtml .
@addTagHelper *, Microsoft.FeatureManagement.AspNetCore
Фильтры MVC
Фильтры действий MVC можно настроить для условного выполнения на основе состояния компонента. Это делается путем регистрации фильтров MVC в многофункциональном режиме.
Конвейер управления функциями поддерживает асинхронные фильтры действий MVC, которые реализуют IAsyncActionFilter
.
services.AddMvc(o =>
{
o.Filters.AddForFeature<SomeMvcFilter>("FeatureX");
});
Приведенный выше код добавляет фильтр MVC с именем SomeMvcFilter
. Этот фильтр активируется только в конвейере MVC, если включен параметр FeatureX.
Razor Pages
Для выполнения страниц Razor MVC может потребоваться включить определенную функцию или один из всех списков функций. Это можно сделать с помощью FeatureGateAttribute
элемента, который можно найти в Microsoft.FeatureManagement.Mvc
пространстве имен.
[FeatureGate("FeatureX")]
public class IndexModel : PageModel
{
public void OnGet()
{
}
}
Приведенный выше код настраивает страницу Razor для включения компонента FeatureX. Если функция не включена, страница создает результат HTTP 404 (NotFound).
При использовании на страницах FeatureGateAttribute
Razor необходимо поместить его в тип обработчика страниц. Его нельзя поместить в отдельные методы обработчика.
Сборка приложений
Библиотеку управления функциями можно использовать для добавления ветвей приложений и ПО промежуточного слоя, которые выполняются условно на основе состояния компонента.
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 Alias Attribute
разделе.
Параметризованные фильтры компонентов
Некоторые фильтры функций требуют параметров, чтобы решить, следует ли включить или нет функцию. Например, фильтр функций браузера может включить функцию для определенного набора браузеров. Возможно, требуется, чтобы браузеры 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; }
}
FeatureFilterEvaluationContext
имеет свойство с именем Parameters
. Эти параметры представляют необработанную конфигурацию, которую фильтр компонентов может использовать для определения того, следует ли включить или нет эту функцию. Чтобы использовать фильтр функций браузера в качестве примера, фильтр может использовать Parameters
для извлечения набора разрешенных браузеров, которые будут указаны для функции, а затем проверить, отправляется ли запрос из одного из этих браузеров.
[FilterAlias("Browser")]
public class BrowserFilter : IFeatureFilter
{
…
public Task<bool> EvaluateAsync(FeatureFilterEvaluationContext context)
{
BrowserFilterSettings settings = context.Parameters.Get<BrowserFilterSettings>() ?? new BrowserFilterSettings();
//
// Here we would use the settings and see if the request was sent from any of BrowserFilterSettings.AllowedBrowsers
}
}
Атрибут псевдонима фильтра
При регистрации фильтра компонентов для флага компонента псевдоним, используемый в конфигурации, — это имя типа фильтра компонентов с суффиксом фильтра , если таковые имеются, удалены. Например, MyCriteriaFilter
в конфигурации будет называться MyCriteria .
"MyFeature": {
"EnabledFor": [
{
"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.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
…
}
Дополнительно: IHttpContextAccessor
/HttpContext
не следует использовать в компонентах Razor серверных приложений Blazor. Рекомендуемый подход к передаче контекста HTTP в приложениях Blazor заключается в копировании данных в службу с областью действия. Для приложений AddScopedFeatureManagement
Blazor следует использовать для регистрации служб управления функциями. Дополнительные сведения см. в Scoped Feature Management Services
разделе.
Предоставление контекста для оценки компонентов
В консольных приложениях нет контекста окружающей среды, например HttpContext
фильтров компонентов, может получить и использовать, чтобы проверить, должна ли функция быть включена или отключена. В этом случае приложениям необходимо предоставить объект, представляющий контекст в системе управления функциями для использования фильтрами компонентов. Это делается с помощью IFeatureManager.IsEnabledAsync<TContext>(string featureName, TContext appContext)
. Объект appContext, предоставляемый диспетчеру функций, можно использовать фильтрами компонентов для оценки состояния компонента.
MyAppContext context = new MyAppContext
{
AccountId = current.Id;
}
if (await featureManager.IsEnabledAsync(feature, context))
{
…
}
Контекстные фильтры компонентов
Контекстные фильтры функций реализуют IContextualFeatureFilter<TContext>
интерфейс. Эти фильтры специальных функций могут воспользоваться контекстом, передаваемым при IFeatureManager.IsEnabledAsync<TContext>
вызове. Параметр TContext
типа в IContextualFeatureFilter<TContext>
описании типа контекста, который фильтр может обрабатывать. Это позволяет разработчику контекстного фильтра функций описать, что необходимо для тех, кто хочет использовать его. Так как каждый тип является потомком объекта, фильтр, реализующий IContextualFeatureFilter<object>
его, можно вызывать для любого предоставленного контекста. Чтобы проиллюстрировать пример более конкретного контекстного фильтра функций, рассмотрите функцию, которая включена, если учетная запись находится в настроенном списке включенных учетных записей.
public interface IAccountContext
{
string AccountId { get; set; }
}
[FilterAlias("AccountId")]
class AccountIdFilter : IContextualFeatureFilter<IAccountContext>
{
public Task<bool> EvaluateAsync(FeatureFilterEvaluationContext featureEvaluationContext, IAccountContext accountId)
{
//
// Evaluate if the feature should be on with the help of the provided IAccountContext
}
}
Мы видим, что AccountIdFilter
требуется, чтобы объект, реализуемый IAccountContext
для предоставления, мог оценить состояние компонента. При использовании этого фильтра функций вызывающий объект должен убедиться, что переданный в объект реализуется IAccountContext
.
Примечание.
Только один интерфейс фильтра признаков может быть реализован одним типом. При попытке добавить фильтр компонентов, реализующий более одного интерфейса фильтра признаков, приводит к тому, что ArgumentException
Использование контекстных и не контекстных фильтров с одинаковым псевдонимом
IFeatureFilter
Фильтры и IContextualFeatureFilter
могут совместно использовать один и тот же псевдоним. В частности, у вас может быть один псевдоним фильтра, которым предоставлен общий доступ к 0 или 1 IFeatureFilter
и 0 или NIContextualFeatureFilter<ContextType>
, если существует не более одного применимого фильтра.ContextType
В следующем фрагменте описывается процесс выбора фильтра при регистрации контекстных и не контекстных фильтров того же имени в приложении.
Предположим, что у вас есть не контекстный фильтр, называемый FilterA
и два контекстных фильтра FilterB
и FilterC, которые принимают TypeB
и TypeC
контексты соответственно. Все три фильтра имеют одинаковый псевдоним SharedFilterName
.
У вас также есть флаг MyFeature
компонента, использующий фильтр SharedFilterName
компонентов в его конфигурации.
Если регистрируются все три фильтра:
- При вызове IsEnabledAsync("MyFeature")
FilterA
используется для оценки флага функции. - При вызове IsEnabledAsync("MyFeature", context), если используется
TypeB
FilterB
тип контекста. Если используетсяTypeC
тип контекста,FilterC
используется. - При вызове IsEnabledAsync("MyFeature", context), если используется
TypeF
FilterA
тип контекста.
Встроенные фильтры компонентов
Существует несколько фильтров функций, которые поставляется с пакетомMicrosoft.FeatureManagement
: PercentageFilter
, TimeWindowFilter
ContextualTargetingFilter
и TargetingFilter
. Все фильтры, кроме TargetingFilter
этого, добавляются автоматически , когда управление функциями регистрируется методом AddFeatureManagement
. Он TargetingFilter
добавляется с WithTargeting
помощью метода, подробно описанного в Targeting
разделе ниже.
Каждый из встроенных фильтров функций имеет собственные параметры. Ниже приведен список фильтров функций вместе с примерами.
Microsoft.Percentage
Этот фильтр предоставляет возможность включить функцию на основе заданного процента.
"EnhancedPipeline": {
"EnabledFor": [
{
"Name": "Microsoft.Percentage",
"Parameters": {
"Value": 50
}
}
]
}
Microsoft.TimeWindow
Этот фильтр предоставляет возможность включить функцию на основе периода времени. Если указан только End
этот параметр, функция рассматривается до этого времени. Если указан только Start
этот параметр, функция рассматривается во всех точках после этого времени.
"EnhancedPipeline": {
"EnabledFor": [
{
"Name": "Microsoft.TimeWindow",
"Parameters": {
"Start": "Wed, 01 May 2019 13:59:59 GMT",
"End": "Mon, 01 Jul 2019 00:00:00 GMT"
}
}
]
}
Период времени можно настроить для периодического повторения. Это может быть полезно для сценариев, когда может потребоваться включить функцию в течение низкого или высокого периода трафика в день или определенные дни недели. Чтобы развернуть отдельное окно времени до повторяющихся окон времени, правило повторения должно быть указано в параметре Recurrence
.
Примечание.
Start
и End
должны быть указаны как для включения Recurrence
.
"EnhancedPipeline": {
"EnabledFor": [
{
"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
Шаблон ежедневного повторения приводит к повтору периода времени на основе нескольких дней между каждым вхождением.
Свойство С сортировкой по релевантности Описание Тип Обязательное поле Должен иметь значение Daily
.Интервал Необязательно Указывает количество дней между каждым вхождением. Значение по умолчанию — 1. Weekly
Еженедельный шаблон повторения приводит к тому, что период времени повторяется в один или несколько дней недели в зависимости от количества недель между каждым набором вхождения.
Свойство С сортировкой по релевантности Описание Тип Обязательное поле Должен иметь значение Weekly
.DaysOfWeek Обязательное поле Указывает, в каких днях недели происходит событие. Интервал Необязательно Указывает количество недель между каждым набором вхождений. Значение по умолчанию — 1. FirstDayOfWeek Необязательно Указывает, какой день считается первым днем недели. Значение по умолчанию: Sunday
.В следующем примере повторяется время каждого другого понедельника и вторника
"Pattern": { "Type": "Weekly", "Interval": 2, "DaysOfWeek": ["Monday", "Tuesday"] }
Примечание.
Start
должно быть допустимым первым вхождением, которое соответствует шаблону повторения. Кроме того, продолжительность периода времени не может превышать частоту ее возникновения. Например, недопустимо, чтобы каждый день повторялось 25-часовое окно времени.
Диапазон повторений
Существует три возможных типа диапазонов повторений: NoEnd
EndDate
и Numbered
.
NoEnd
Диапазон
NoEnd
приводит к тому, что повторение происходит на неопределенный срок.Свойство С сортировкой по релевантности Описание Тип Обязательное поле Должен иметь значение NoEnd
.EndDate
Диапазон
EndDate
приводит к возникновению периода времени в течение всех дней, которые соответствуют применимому шаблону до даты окончания.Свойство С сортировкой по релевантности Описание Тип Обязательное поле Должен иметь значение 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
приводит к возникновению фиксированного количества времени (на основе шаблона).Свойство С сортировкой по релевантности Описание Тип Обязательное поле Должен иметь значение Numbered
.NumberOfOccurrences Обязательное поле Указывает количество вхождения. В следующем примере будет повторяться временное окно в понедельник и вторник, пока не будет три вхождения, которые соответственно происходят 1 апреля, 2(Tue) и 8 апреля (Mon).
"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
Этот фильтр предоставляет возможность включить функцию для целевой аудитории. Подробное объяснение целевого назначения объясняется в приведенном ниже разделе о целевом объекте . Параметры фильтра включают Audience
объект, описывающий пользователей, групп, исключенных пользователей и групп, а также процент базы пользователей по умолчанию, который должен иметь доступ к этой функции. Каждый объект группы, указанный в Groups
разделе, также должен указывать, какой процент членов группы должен иметь доступ. Если пользователь указан в Exclusion
разделе, либо непосредственно, либо если пользователь находится в исключенной группе, функция отключена. В противном случае, если пользователь указан в Users
разделе напрямую, или если пользователь находится в процентах от любого из развернутых групп или если пользователь попадает в процент развертывания по умолчанию, то этот пользователь будет включен.
"EnhancedPipeline": {
"EnabledFor": [
{
"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
или последним сегментом, который в случае Microsoft.Percentage
имеет значение Percentage
.
Таргетинг
Цель — это стратегия управления функциями, которая позволяет разработчикам постепенно развертывать новые функции в своей пользовательской базе. Стратегия основана на концепции целевой аудитории для набора пользователей, известных как целевая аудитория. Аудитория состоит из конкретных пользователей, групп, исключенных пользователей и групп, и указанного процента всей базы пользователей. Группы, включенные в аудиторию, могут быть разбиты дальше на проценты их общих членов.
Ниже приведен пример прогрессивного развертывания для новой функции Beta:
- Отдельные пользователи Джефф и Алисия получают доступ к бета-версии
- Другой пользователь, Mark, просит принять участие и включен.
- Двадцать процентов группы, известной как "Ring1", включены в бета-версию.
- Число пользователей Ring1, включенных в бета-версию, составляет до 100 процентов.
- Пять процентов пользовательской базы включены в бета-версию.
- Процент развертывания вырос до 100 процентов, и функция полностью развернута.
Эта стратегия развертывания компонента встроена в библиотеку с помощью включенного фильтра компонентов Microsoft.Targeting .
Назначение в веб-приложении
Пример веб-приложения, использующего фильтр функций целевого объекта, доступен в примере проекта FeatureFlagDemo .
Чтобы начать использование TargetingFilter
приложения, его необходимо добавить в коллекцию служб приложения так же, как и любой другой фильтр компонентов. В отличие от других встроенных фильтров, служба TargetingFilter
использует другую службу для добавления в коллекцию служб приложения. Эта служба является .ITargetingContextAccessor
Тип реализации, используемый для ITargetingContextAccessor
службы, должен быть реализован приложением, использующим целевой фильтр. Ниже приведен пример настройки управления функциями в веб-приложении для использования TargetingFilter
с реализацией вызываемой ITargetingContextAccessor
HttpContextTargetingContextAccessor
функции.
services.AddFeatureManagement()
.WithTargeting<HttpContextTargetingContextAccessor>();
Целевой метод доступа к контексту и TargetingFilter
регистрируется путем вызова IFeatureManagementBuilder
WithTargeting<T>
.
ITargetingContextAccessor
Для использования TargetingFilter
в веб-приложении требуется реализация ITargetingContextAccessor
. Это связано с тем, что при выполнении целевой оценки требуются такие сведения, как то, что пользователь в настоящее время оценивает. Эта информация называется контекстом целевого объекта. Различные веб-приложения могут извлекать эти сведения из разных мест. Некоторые распространенные примеры того, где приложение может извлечь контекст целевого объекта, — это контекст HTTP запроса или база данных.
Пример, который извлекает сведения о контексте целевого объекта из контекста HTTP приложения, включен в пример проекта FeatureFlagDemo . Этот метод зависит от использования IHttpContextAccessor
, который обсуждается здесь.
Назначение в консольном приложении
Фильтр целевых объектов зависит от контекста целевого объекта, чтобы оценить, следует ли включить функцию. Этот контекст целевого объекта содержит такие сведения, как оценка пользователя и группы пользователей. В консольных приложениях обычно нет контекста окружающей среды для потока этих сведений в целевой фильтр, поэтому он должен передаваться непосредственно при FeatureManager.IsEnabledAsync
вызове. Это поддерживается с помощью .ContextualTargetingFilter
Приложения, которые должны с плавать контекстом целевого объекта в диспетчере функций, должны использовать это вместо TargetingFilter.
Так как ContextualTargetingFilter
это IContextualTargetingFilter<ITargetingContext>
реализация ITargetingContext
должна передаваться IFeatureManager.IsEnabledAsync
в нее, чтобы она могла оценивать и включать функцию.
IFeatureManager fm;
…
// userId and groups defined somewhere earlier in application
TargetingContext targetingContext = new TargetingContext
{
UserId = userId,
Groups = groups
};
await fm.IsEnabledAsync(featureName, targetingContext);
По-прежнему ContextualTargetingFilter
используется псевдоним фильтра компонентов 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, которая включает в себя предоставление другой версии функции различным сегментам пользовательской базы и выбор версии на основе взаимодействия с пользователем. В этой библиотеке эта функция включена путем представления различных конфигураций компонента с вариантами.
Варианты позволяют флагу функции стать более простым флагом включения и выключения. Вариант представляет значение флага компонента, которое может быть строкой, числом, логическим или даже объектом конфигурации. Флаг компонента, объявляющий варианты, должен определять, в каких обстоятельствах следует использовать каждый вариант, который подробно рассматривается в разделе "Выделение вариантов ".
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(MyFeatureFlags.FeatureU, 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-файле. Ниже приведен пример флага функции variant.
{
"feature_management": {
"feature_flags": [
{
"id": "MyVariantFeatureFlag",
"enabled": true,
"allocation": {
"default_when_enabled": "Small",
"group": [
{
"variant": "Big",
"groups": [
"Ring1"
]
}
]
},
"variants": [
{
"name": "Big"
},
{
"name": "Small"
}
]
}
]
}
}
Определение вариантов
Каждый вариант имеет два свойства: имя и конфигурацию. Имя используется для ссылки на конкретный вариант, а конфигурация — это значение этого варианта. Конфигурацию можно задать с помощью либо configuration_reference
configuration_value
свойств. configuration_reference
— это строковый путь, ссылающийся на раздел текущей конфигурации, содержащей объявление флага компонента. configuration_value
— это встроенная конфигурация, которая может быть строкой, номером, логическим объектом или объектом конфигурации. Если указаны оба значения, используется configuration_value
. Если ни указано, свойство возвращаемого варианта Configuration
будет иметь значение NULL.
Список всех возможных вариантов определяется для каждой функции в свойстве variants
.
{
"feature_management": {
"feature_flags": [
{
"id": "MyVariantFeatureFlag",
"variants": [
{
"name": "Big",
"configuration_reference": "ShoppingCart:Big"
},
{
"name": "Small",
"configuration_value": {
"Size": 300
}
}
]
}
]
},
"ShoppingCart": {
"Big": {
"Size": 600,
"Color": "green"
},
"Small": {
"Size": 300,
"Color": "gray"
}
}
}
Выделение вариантов
Процесс выделения вариантов компонента определяется свойством 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_reference": "ShoppingCart:Big"
},
{
"name": "Small",
"configuration_value": "300px"
}
]
Параметр allocation
компонента имеет следующие свойства:
Свойство | Description |
---|---|
default_when_disabled |
Указывает, какой вариант следует использовать при запросе варианта во время отключения функции. |
default_when_enabled |
Указывает, какой вариант следует использовать при запросе варианта, если компонент считается включенным, и другой вариант не был назначен пользователю. |
user |
Задает вариант и список пользователей, которым должен быть назначен этот вариант. |
group |
Задает вариант и список групп. Вариант будет назначен, если пользователь находится по крайней мере в одной из групп. |
percentile |
Задает вариант и процентный диапазон, в котором вычисляемый процент пользователя должен соответствовать назначенному варианту. |
seed |
Значение, на котором основаны процентные расчеты percentile . Процентное вычисление для конкретного пользователя будет одинаковым для всех функций, если используется одно и то же seed значение. Если значение не seed указано, то начальное значение по умолчанию создается на основе имени функции. |
В приведенном выше примере, если функция не включена, диспетчер функций назначит вариант, помеченный текущим default_when_disabled
пользователем, что в Small
данном случае.
Если функция включена, диспетчер функций проверит user
group
и percentile
выделения в этом порядке, чтобы назначить вариант. В этом примере, если вычисляемый пользователь называется Marsha
, в группе с именем Ring1
или пользователь попадает между 0 и 10-м процентилем, то указанный вариант назначается пользователю. В этом случае все эти варианты возвращаются Big
. Если ни одно из этих выделений не соответствует, пользователю назначается default_when_enabled
вариант.Small
Логика выделения аналогична фильтру функций Microsoft.Targeting , но существуют некоторые параметры, которые присутствуют в целевом расположении, которые не находятся в выделении, и наоборот. Результаты целевого и распределения не связаны.
Примечание.
Чтобы разрешить выделение вариантов функций, необходимо зарегистрировать ITargetingContextAccessor
. Это можно сделать, вызвав WithTargeting<T>
метод.
Переопределение состояния с включенным вариантом
Варианты можно использовать для переопределения состояния включенного флага компонента. Это дает возможность расширить оценку флага функции. Если вызывающий объект проверяет, включен ли флаг с вариантами, диспетчер функций проверяет, настроен ли вариант, назначенный текущему пользователю, для переопределения результата. Это делается с помощью необязательного свойства status_override
variant. По умолчанию это свойство имеет значение None
, что означает, что вариант не влияет на то, включен или отключен флаг. Параметр status_override
позволяет варианту Enabled
при выборе переопределить флаг, который необходимо включить. Параметр status_override
для Disabled
получения противоположной функциональности, поэтому отключение флага при выборе варианта. Невозможно переопределить функцию enabled
с состоянием false
переопределения.
Если вы используете флаг функции с двоичными вариантами, 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
, функция теперь будет считаться отключенной.
Варианты внедрения зависимостей
Флаги функций variant можно использовать в сочетании с внедрением зависимостей для поверхности различных реализаций службы для разных пользователей. Это достигается с помощью IVariantServiceProvider<TService>
интерфейса.
IVariantServiceProvider<IAlgorithm> algorithmServiceProvider;
...
IAlgorithm forecastAlgorithm = await algorithmServiceProvider.GetServiceAsync(cancellationToken);
В приведенном выше IVariantServiceProvider<IAlgorithm>
фрагменте извлекается реализация IAlgorithm
из контейнера внедрения зависимостей. Выбранная реализация зависит от:
- Флаг компонента, в который
IAlgorithm
была зарегистрирована служба. - Выделенный вариант для этой функции.
Приложение IVariantServiceProvider<T>
становится доступным путем вызова IFeatureManagementBuilder.WithVariantService<T>(string featureName)
. Пример см. ниже.
services.AddFeatureManagement()
.WithVariantService<IAlgorithm>("ForecastAlgorithm");
Приведенный выше вызов предоставляется IVariantServiceProvider<IAlgorithm>
в коллекции служб. IAlgorithm
Реализации должны быть добавлены отдельно с помощью метода добавления, напримерservices.AddSingleton<IAlgorithm, SomeImplementation>()
. Реализация IAlgorithm
этого IVariantServiceProvider
метода зависит от флага ForecastAlgorithm
функции variant. Если реализация IAlgorithm
не добавлена в коллекцию служб, IVariantServiceProvider<IAlgorithm>.GetServiceAsync()
возвращает задачу с пустым результатом.
{
// The example variant feature flag
"id": "ForecastAlgorithm",
"enabled": true,
"variants": [
{
"Name": "AlgorithmBeta"
},
...
]
}
Атрибут псевдонима службы variant
[VariantServiceAlias("Beta")]
public class AlgorithmBeta : IAlgorithm
{
...
}
Поставщик услуг variant будет использовать имена типов реализаций для сопоставления выделенного варианта. Если служба вариантов украшена VariantServiceAliasAttribute
атрибутом, имя, объявленное в этом атрибуте, должно использоваться в конфигурации для ссылки на эту службу вариантов.
Телеметрия
При развертывании изменения флага функции часто важно проанализировать его влияние на приложение. Например, вот несколько вопросов, которые могут возникнуть:
- Включены ли флаги и отключены ли они должным образом?
- Получают ли целевые пользователи доступ к определенной функции должным образом?
- Какой вариант отображает конкретный пользователь?
Эти типы вопросов можно ответить с помощью выбросов и анализа событий оценки флага признаков. Эта библиотека поддерживает выдачу этих событий с помощью издателей телеметрии. Один или несколько издателей телеметрии могут быть зарегистрированы для публикации событий при оценке флагов компонентов.
Включение телеметрии
По умолчанию флаги компонентов не создают данные телеметрии. Чтобы опубликовать данные телеметрии для заданного флага компонента, флаг ДОЛЖЕН объявить, что он включен для выбросов телеметрии.
Для флагов компонентов, определенных в appsettings.json
, это делается с помощью telemetry
свойства.
{
"feature_management": {
"feature_flags": [
{
"id": "MyFeatureFlag",
"enabled": true,
"telemetry": {
"enabled": true
}
}
]
}
}
Приведенный выше фрагмент кода приложения определяет флаг компонента, который MyFeatureFlag
включен для телеметрии. Это указывает telemetry
объект, который задает enabled
значение true. Значение enabled
свойства должно быть true
для публикации телеметрии для флага.
Раздел telemetry
флага компонента имеет следующие свойства:
Свойство | Description |
---|---|
enabled |
Указывает, следует ли публиковать данные телеметрии для флага компонента. |
metadata |
Коллекция пар "ключ-значение", моделироваемая как словарь, которая может использоваться для присоединения пользовательских метаданных о флаге компонента для оценки событий. |
Пользовательские издатели телеметрии
Пользовательская обработка телеметрии флага компонента возможна путем реализации ITelemetryPublisher
и регистрации его в диспетчере функций. При оценке флага компонента с включенной телеметрией зарегистрированный издатель телеметрии получает возможность опубликовать соответствующее событие оценки.
public interface ITelemetryPublisher
{
ValueTask PublishEvent(EvaluationEvent evaluationEvent, CancellationToken cancellationToken);
}
Тип EvaluationEvent
можно найти здесь для справки.
Регистрация издателей телеметрии выполняется при вызове AddFeatureManagement()
. Ниже приведен пример настройки управления функциями для отправки данных телеметрии с реализацией вызываемой ITelemetryPublisher
MyTelemetryPublisher
функции.
builder.services
.AddFeatureManagement()
.AddTelemetryPublisher<MyTelemetryPublisher>();
Издатель телеметрии Application Insights
Пакет Microsoft.FeatureManagement.Telemetry.ApplicationInsights
предоставляет встроенную реализацию издателя телеметрии, которая отправляет данные оценки флага компонента в Application Insights. Чтобы воспользоваться этим, добавьте ссылку на пакет и зарегистрируйте издателя телеметрии Application Insights, как показано ниже.
builder.services
.AddFeatureManagement()
.AddTelemetryPublisher<ApplicationInsightsTelemetryPublisher>();
Примечание.
Базовый Microsoft.FeatureManagement
пакет не включает этот издатель телеметрии.
Пример его использования можно найти в примере EvaluationDataToApplicationInsights .
Необходимые условия
Этот издатель телеметрии зависит от уже настроенной и зарегистрированной в качестве службы приложений Application Insights. Например, это сделано в примере приложения.
Кэширование
Состояние компонента предоставляется IConfiguration
системой. Ожидается, что любое кэширование и динамическое обновление обрабатывается поставщиками конфигурации. Диспетчер функций запрашивает IConfiguration
последнее значение состояния компонента всякий раз, когда функция будет включена.
Снимок
Существуют сценарии, которые требуют, чтобы состояние функции оставалось согласованным в течение времени существования запроса. Значения, IFeatureManager
возвращаемые стандартом, могут измениться, если IConfiguration
источник, из который он извлекается, обновляется во время запроса. Это можно предотвратить с помощью IFeatureManagerSnapshot
. IFeatureManagerSnapshot
можно получить таким же образом, как IFeatureManager
и . IFeatureManagerSnapshot
реализует интерфейс IFeatureManager
, но кэширует первое вычисляемое состояние компонента во время запроса и возвращает то же состояние функции во время его существования.
Поставщики пользовательских функций
Реализация пользовательского поставщика функций позволяет разработчикам извлекать флаги функций из источников, таких как база данных или служба управления функциями. Включенный поставщик функций, используемый по умолчанию, извлекает флаги компонентов из системы конфигурации .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()
Следующие шаги
Чтобы узнать, как использовать флаги функций в приложениях, перейдите к следующим кратким руководствам.
Чтобы узнать, как использовать фильтры функций, перейдите к следующим руководствам.
Чтобы узнать, как выполнять эксперименты с флагами функций variant, перейдите к следующему руководству.
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по