ما هي أعلام الميزات ولماذا تحتاجها
\nتخيل: لقد كتبت ميزة جديدة رائعة - على سبيل المثال، بحث ذكي مع الإكمال التلقائي. كل شيء تم اختباره، والكود اجتاز المراجعة. لكنك لست متأكدًا بنسبة 100% أن المستخدمين سيقبلونها. أو تخشى أنها ستتعطل تحت الضغط. ماذا تفعل؟
\nفي السابق، كانت الإجابة بسيطة: "انشرها في الإنتاج وصلّ". اليوم نحن أكثر ذكاءً. نستخدم أعلام الميزات (feature flags, feature toggles) - آلية تسمح بتشغيل وإيقاف الوظائف بسرعة، دون إعادة ترجمة أو إعادة نشر.
\nفي هذه المقالة على PythonLib، سنشرح كيفية دمج أعلام الميزات في مشاريع C# - من أبسط تنفيذ إلى سيناريوهات متقدمة مع اختبار A/B والإصدارات التجريبية.
\n\nلماذا أعلام الميزات ضرورية لمطور C#
\nأعلام الميزات C# تحل ثلاث مهام رئيسية:
\n- \n
- النشر الآمن: انشر الكود في الإنتاج حتى لو كانت الميزة غير جاهزة بعد. فقط قم بإيقاف العلم. \n
- الإيقاف الفوري: حدث خطأ ما؟ نقرة واحدة في لوحة الإدارة - وتختفي الميزة الإشكالية. \n
- إدارة مرنة للوظائف: قم بتشغيل الميزات لمستخدمين محددين، مناطق، أو حسب الوقت. \n
والأفضل من ذلك: لـ إدارة الوظائف في .NET لا حاجة لاختراع العجلة - هناك مكتبة جاهزة Microsoft.FeatureManagement.
أسهل طريقة: ملف التكوين
\nلنبدأ بالنهج الأساسي - عبر appsettings.json. هذا مثالي لـ تبديل الميزات .NET البسيط.
الخطوة 1. إضافة الإعدادات
\n{\n "FeatureManagement": {\n "NewSearchEngine": true,\n "DarkMode": false,\n "BetaDashboard": true\n }\n}\n\nالخطوة 2. تسجيل الخدمة
\nفي Program.cs أضف:
builder.Services.AddFeatureManagement();\n\nالخطوة 3. الاستخدام في الكود
\npublic class SearchController\n{\n private readonly IFeatureManager _featureManager;\n\n public SearchController(IFeatureManager featureManager)\n {\n _featureManager = featureManager;\n }\n\n public async Task<IActionResult> Search(string query)\n {\n if (await _featureManager.IsEnabledAsync("NewSearchEngine"))\n {\n return View("NewSearch", await _newEngine.SearchAsync(query));\n }\n return View("LegacySearch", await _oldEngine.SearchAsync(query));\n }\n}\nتم! الآن، لتشغيل الميزة الجديدة، يكفي تغيير true إلى false في ملف التكوين وإعادة تشغيل التطبيق. لكننا نريد بدون إعادة تشغيل؟
أعلام الميزات الديناميكية: التبديل دون إعادة تشغيل
\nلـ الميزات الشرطية C# دون إعادة تحميل، نستخدم موفري التكوين الذين يقومون بتحميل التغييرات. الخيار الأفضل هو قاعدة البيانات أو Redis.
\n\nإنشاء موفر من قاعدة البيانات
\npublic class DatabaseFeatureDefinitionProvider : IFeatureDefinitionProvider\n{\n private readonly AppDbContext _db;\n\n public DatabaseFeatureDefinitionProvider(AppDbContext db)\n {\n _db = db;\n }\n\n public async Task<FeatureDefinition> GetFeatureDefinitionAsync(string featureName)\n {\n var feature = await _db.FeatureFlags\n .FirstOrDefaultAsync(f => f.Name == featureName);\n \n return feature != null \n ? new FeatureDefinition { Name = feature.Name, EnabledFor = feature.EnabledFor }\n : null;\n }\n\n public IAsyncEnumerable<FeatureDefinition> GetAllFeatureDefinitionsAsync()\n {\n return _db.FeatureFlags\n .Select(f => new FeatureDefinition { Name = f.Name, EnabledFor = f.EnabledFor })\n .AsAsyncEnumerable();\n }\n}\n\nالتسجيل:
\nbuilder.Services.AddFeatureManagement