慣性聚合 関心のあるブログ、ニュース、テクノロジーを効率的に追跡
原文を読む 慣性聚合で開く

おすすめ購読元

Google DeepMind News
Google DeepMind News
人人都是产品经理
人人都是产品经理
M
MIT News - Artificial intelligence
博客园 - 叶小钗
MyScale Blog
MyScale Blog
V
Visual Studio Blog
月光博客
月光博客
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
量子位
I
InfoQ
有赞技术团队
有赞技术团队
阮一峰的网络日志
阮一峰的网络日志
Jina AI
Jina AI
V
V2EX
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Blog — PlanetScale
Blog — PlanetScale
Last Week in AI
Last Week in AI
雷峰网
雷峰网
Stack Overflow Blog
Stack Overflow Blog
博客园 - Franky

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python)
.NET 8における機能フラグ:ASP.NET Core、ミニマルAPI、Blazor
Domenico Gio · 2026-05-25 · via DEV Community

この投稿は元々rollgate.io/blog/feature-flags-aspnet-coreに公開されました.

すべての.NETチームは最終的に同じ壁にぶつかります:ステージングで機能が準備できているが、プロダクションにプッシュするには一度にすべてのユーザーにスイッチを切り替える必要があります。何かが壊れる場合——誤った仮定、エッジケース、パフォーマンスの回帰——あなたの唯一の回復手段はロールバックと再デプロイです.

機能フラグは、デプロイメントとリリースを分離することでこの問題を解決します。コードをフラグの後ろに配置し、ダッシュボードから誰がそれを見るかを制御し、パイプラインを触ることなく管理します。1%のユーザーから始め、メトリクスを監視し、100%に拡大します。もしどの段階でもエラーが急増した場合、数秒でフラグを無効にします.

クイックスタート:.NET 8での機能フラグ

NuGetからRollgate SDKをインストールします:

dotnet add package Rollgate.SDK

フルスクリーンモードに入る フルスクリーンモードを終了

アプリケーション起動時にクライアントを初期化

using Rollgate.SDK;

var client = new RollgateClient(new RollgateConfig
{
    ApiKey = Environment.GetEnvironmentVariable("ROLLGATE_API_KEY") ?? "",
});

await client.InitializeAsync();

if (client.IsEnabled("new-checkout", false))
{
    Console.WriteLine("New checkout enabled");
}

client.Dispose();

フルスクリーンモードに入る フルスクリーンモードを終了

InitializeAsync()の後、IsEnabledの各呼び出しはメモリ内の辞書から読み取る—1桁のマイクロ秒オーバーヘッド.

依存性注入に登録

ASP.NET Coreでは、クライアントをシングルトンとして登録し、さらに小さくIFeatureFlags抽象化によりコントローラーがテスト可能になる

// Program.cs
builder.Services.AddSingleton<RollgateClient>(sp =>
{
    var client = new RollgateClient(new RollgateConfig
    {
        ApiKey = builder.Configuration["Rollgate:ApiKey"] ?? "",
        RefreshInterval = TimeSpan.FromSeconds(30),
    });
    // Tutorial simplicity. In production, prefer IHostedService.
    client.InitializeAsync().GetAwaiter().GetResult();
    return client;
});

builder.Services.AddSingleton<IFeatureFlags, RollgateFeatureFlags>();

フルスクリーンモードに入る フルスクリーンモードを終了する

public interface IFeatureFlags
{
    bool IsEnabled(string flagKey, bool defaultValue = false);
}

public sealed class RollgateFeatureFlags : IFeatureFlags
{
    private readonly RollgateClient _client;
    public RollgateFeatureFlags(RollgateClient client) => _client = client;
    public bool IsEnabled(string key, bool def = false) => _client.IsEnabled(key, def);
}

フルスクリーンモードに入る フルスクリーンモードを終了する

ASP.NET Core コントローラーにおける機能フラグ

インジェクトIFeatureFlags、SDKの種類そのものではありません:

[ApiController]
[Route("api/[controller]")]
public class CheckoutController : ControllerBase
{
    private readonly IFeatureFlags _flags;

    public CheckoutController(IFeatureFlags flags) => _flags = flags;

    [HttpPost]
    public async Task<IActionResult> CreateOrder([FromBody] OrderRequest request)
    {
        return _flags.IsEnabled("checkout-v2", false)
            ? Ok(await ProcessV2Async(request))
            : Ok(await ProcessV1Async(request));
    }
}

フルスクリーンモードを開始 フルスクリーンモードを終了

ユーザーを特定する — セッションごとに1回、リクエストごとにしない

RollgateClient.IdentifyAsync HTTPリクエストを発行し、フラグをリフレッシュします。 すべてのリクエストで呼び出さないで — それにより、各エンドポイントごとにネットワークのラウンドトリップが追加され、メモリ内の評価モデルが破壊されます。

適切な場所はユーザーごとに一度だけ実行されるアクションフィルタであり、その後ショートサーキットします:

public class FeatureFlagIdentityFilter : IAsyncActionFilter
{
    private readonly RollgateClient _client;
    private static readonly HashSet<string> _identified = new();
    private static readonly SemaphoreSlim _gate = new(1, 1);

    public FeatureFlagIdentityFilter(RollgateClient client) => _client = client;

    public async Task OnActionExecutionAsync(ActionExecutingContext ctx, ActionExecutionDelegate next)
    {
        var userId = ctx.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
        if (!string.IsNullOrEmpty(userId) && !_identified.Contains(userId))
        {
            await _gate.WaitAsync();
            try
            {
                if (!_identified.Contains(userId))
                {
                    await _client.IdentifyAsync(new UserContext { Id = userId });
                    _identified.Add(userId);
                }
            }
            finally { _gate.Release(); }
        }
        await next();
    }
}

フルスクリーンモードを開始 フルスクリーンモードを終了

本番環境用クリーンナー:ログイン時にIdentifyAsyncを一度だけ呼び出し、ログアウトまで再度は呼び出さない。

最小APIにおける機能フラグ

app.MapPost("/api/search", async (SearchRequest req, IFeatureFlags flags) =>
{
    return flags.IsEnabled("semantic-search", false)
        ? Results.Ok(await RunSemanticSearchAsync(req.Query))
        : Results.Ok(await RunKeywordSearchAsync(req.Query));
});

フルスクリーンモードを開始 フルスクリーンモードを終了

エンドポイントフィルタで全ルートをゲートし、リクエストサービスからIFeatureFlagsを解決します:

public static class FeatureFlagEndpointExtensions
{
    public static TBuilder RequireFeature<TBuilder>(this TBuilder builder, string flagKey)
        where TBuilder : IEndpointConventionBuilder
    {
        return builder.AddEndpointFilter(async (context, next) =>
        {
            var flags = context.HttpContext.RequestServices.GetRequiredService<IFeatureFlags>();
            if (!flags.IsEnabled(flagKey, false)) return Results.NotFound();
            return await next(context);
        });
    }
}

app.MapGet("/api/v2/analytics", GetAnalyticsV2Handler)
   .RequireFeature("analytics-v2")
   .RequireAuthorization();

フルスクリーンモードを開始 フルスクリーンモードを終了

Blazor Serverの機能フラグ

@page "/checkout"
@inject IFeatureFlags Flags
@inject AuthenticationStateProvider AuthStateProvider

@if (_showNewCheckout) { <NewCheckoutFlow /> } else { <LegacyCheckoutFlow /> }

@code {
    private bool _showNewCheckout;

    protected override void OnInitialized()
    {
        // Runs once per circuit, not per render.
        _showNewCheckout = Flags.IsEnabled("checkout-v2", false);
    }
}

フルスクリーンモードを開始 フルスクリーンモードを終了

Blazor WebAssemblyの場合、Program.csの前にサーバーからフラグを取得しますRunAsync():

var host = builder.Build();
await host.Services.GetRequiredService<FlagService>().LoadAsync();
await host.RunAsync();

フルスクリーンモードを開始 フルスクリーンモードを終了

C言語での機能フラグのテスト

コントローラーがIFeatureFlagsに依存するため、モッキングフレームワークは不要です:

public class FakeFeatureFlags : IFeatureFlags
{
    private readonly Dictionary<string, bool> _flags;
    public FakeFeatureFlags(Dictionary<string, bool>? f = null) => _flags = f ?? new();
    public bool IsEnabled(string key, bool def = false)
        => _flags.TryGetValue(key, out var v) ? v : def;
}

public class CheckoutControllerTests
{
    [Fact]
    public async Task Returns_V2_When_Flag_Enabled()
    {
        var flags = new FakeFeatureFlags(new() { ["checkout-v2"] = true });
        var controller = new CheckoutController(flags);
        var result = await controller.CreateOrder(new OrderRequest { Amount = 99 });
        // assert v2 path
    }
}

フルスクリーンモードを開始 フルスクリーンモードを終了

常に両方のフラグ状態をテストします。

様々なロールアウトとユーザー対象

ユーザーアトリビュートを識別する際(セッションごとに1回)に渡してください:

await _client.IdentifyAsync(new UserContext
{
    Id = userId,
    Email = userEmail,
    Attributes = new Dictionary<string, object?>
    {
        ["plan"] = user.SubscriptionPlan,
        ["country"] = user.Country,
    }
});

フルスクリーンモードを開始 フルスクリーンモードを終了

ダッシュボードでパーセンテージロールアウトとアトリビュートターゲティングを設定 — SDKはすべてのルールをローカルで評価し、評価ごとにAPI呼び出しは不要です。

FAQ

2026年の.NETの機能フラグのアプローチは何ですか?

  • 実行時変更なしのシンプルなトグル→Microsoft.FeatureManagement
  • CNCFベンダーニュートラルSDK → OpenFeature .NET
  • ダッシュボード+ターゲティング+段階的なロールアウト → マネージドサービス(Rollgate、LaunchDarklyなど)

.NETバックグラウンドサービスと互換性がありますか?
はい。RollgateClientをシングルトンとして登録し、BackgroundServiceに注入し、IsEnabledを使用してExecuteAsyncで使用します。

起動時にInitializeAsyncが失敗した場合どうしますか?
キャッシュが存在しない場合、例外が発生します。デフォルトの設定で処理を続けるか、エラーを発生させる(通常はエラーを早めに検出する方が安全です)。


詳細なバージョン(サーキットブレーカー設定、キルスイッチのためのSSEストリーミング、Blazor WebAssemblyパターンを含む)については、rollgate.io/blog/feature-flags-aspnet-coreを参照してください。

無料のRollgateアカウントを作成するには、https://app.rollgate.io/registerを利用してください。 — クレジットカード不要。