Смена провайдера feature flags обычно означает переписывание интеграции. OpenFeature это открытый стандарт под крылом CNCF, который даёт единый vendor-agnostic API: меняете провайдера, меняете одну строчку, код не трогаете.
Установка
dotnet add package OpenFeature
Требования: .NET 8+ или .NET Framework 4.6.2+
Минимальный пример:
await Api.Instance.SetProviderAsync(new InMemoryProvider());
var client = Api.Instance.GetClient();
bool v2Enabled = await client.GetBooleanValueAsync("v2_enabled", false);
if (v2Enabled)
{
// новая логика
}
Флаги с контекстом
Передавайте данные о пользователе/запросе для контекстно-зависимых решений:
// Глобально
EvaluationContext ctx = EvaluationContext.Builder()
.Set("region", "us-east-1")
.Build();
Api.Instance.SetContext(ctx);
// Или прямо в вызове
bool flagValue = await client.GetBooleanValueAsync(
"some-flag", false, reqCtx);
Логика вокруг вычисления флага
Добавляйте поведение на любом этапе: до, после, при ошибке, в любом случае.
// Глобально для всех вызовов
Api.Instance.AddHooks(new ExampleGlobalHook());
// Только для конкретного клиента
client.AddHooks(new ExampleClientHook());
Встроенный
LoggingHook пишет детальные логи через Microsoft.Extensions.Logging.Реакция на изменения
Api.Instance.AddHandler(
ProviderEventTypes.ProviderReady,
(eventDetails) => Console.WriteLine(eventDetails.Type)
);
Подписывайтесь на
ProviderReady, ProviderError, ProviderConfigurationChanged.Dependency Injection (экспериментально)
dotnet add package OpenFeature.Hosting
builder.Services.AddOpenFeature(featureBuilder => {
featureBuilder
.AddInMemoryProvider()
.AddHook<LoggingHook>();
});Поддержка domain-scoped провайдеров: разные провайдеры для разных частей приложения.
Несколько провайдеров одновременно с разными стратегиями:
- FirstMatchStrategy — первый ненулевой результат
- FirstSuccessfulStrategy — первый успешный, игнорируя ошибки
- ComparisonStrategy — параллельное выполнение + сравнение результатов
var multiProvider = new MultiProvider(providerEntries, new FirstMatchStrategy());
await Api.Instance.SetProviderAsync(multiProvider);
Собственный провайдер:
public class MyProvider : FeatureProvider
{
public override Metadata GetMetadata() =>
new Metadata("My Provider");
public override Task<ResolutionDetails<bool>> ResolveBooleanValueAsync(
string flagKey, bool defaultValue,
EvaluationContext? context = null, ...)
{
// ваша логика
}
// + ResolveString, ResolveInteger, ResolveDouble, ResolveStructure
}
Для ASP.NET Core один раз настроили контекст на входе запроса, и он автоматически попадает во все вычисления флагов в рамках этого запроса:
Api.Instance.SetTransactionContextPropagator(
new AsyncLocalTransactionContextPropagator());
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека шарписта
#sharp_view
