نوصيك بالتعرف على المواد: Metanit - Configuration ، How Configuration Works in .NET Core .
صياغة المشكلة
تحتاج إلى تنفيذ تطبيق ASP NET Core مع القدرة على تحديث التكوين بتنسيق JSON في وقت التشغيل. أثناء تحديث التكوين ، يجب أن تستمر الجلسات قيد التشغيل حاليًا في العمل مع خيارات التكوين السابقة. بعد تحديث التكوين ، يجب تحديث / استبدال الكائنات المستخدمة بأخرى جديدة.
يجب إلغاء تسلسل التكوين ، ويجب ألا يكون هناك وصول مباشر إلى كائنات تكوين IC من وحدات التحكم. يجب فحص قيم القراءة للتأكد من صحتها ، وإذا كانت غير موجودة ، فيجب استبدالها بالقيم الافتراضية. يجب أن يعمل التنفيذ في حاوية Docker.
عمل التكوين الكلاسيكي
GitHub: ConfigurationTemplate_1
يعتمد المشروع على قالب ASP NET Core MVC. يتم استخدام موفر تكوين JsonConfigurationProvider للعمل مع ملفات تكوين JSON . لإضافة القدرة على إعادة تحميل تكوين التطبيق أثناء العملية ، أضف المعلمة: "reloadOnChange: true".
في ملف Startup.cs ، استبدل :
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
على
public Startup(IConfiguration configuration)
{
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
configuration = builder.Build();
Configuration = configuration;
}
.AddJsonFile - يضيف ملف JSON ، reloadOnChange: true يشير إلى أنه عند تغيير معلمات ملف التكوين ، سيتم إعادة تحميلها دون الحاجة إلى إعادة تحميل التطبيق.
محتوى ملف appsettings.json :
{
"AppSettings": {
"Parameter1": "Parameter1 ABC",
"Parameter2": "Parameter2 ABC"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
ستستخدم وحدات التحكم في التطبيق الخدمة: ServiceABC بدلاً من الوصول المباشر إلى التكوين. ServiceABC هي فئة تأخذ القيم الأولية من ملف التكوين. في هذا المثال ، تحتوي فئة ServiceABC على خاصية عنوان واحدة فقط . محتوى
ملف ServiceABC.cs :
public class ServiceABC
{
public string Title;
public ServiceABC(string title)
{
Title = title;
}
public ServiceABC()
{ }
}
لاستخدام ServiceABC ، تحتاج إلى إضافته كخدمة وسيطة إلى تطبيقك. أضف الخدمة كـ AddTransient ، والتي يتم إنشاؤها في كل مرة تصل إليها ، باستخدام التعبير:
services.AddTransient<IYourService>(o => new YourService(param));عظيم للخدمات خفيفة الوزن التي لا تستهلك الذاكرة أو الموارد. قراءة معلمات التكوين في Startup.cs تتم باستخدام IConfiguration ، والتي تستخدم سلسلة استعلام تشير إلى المسار الكامل لموقع القيمة ، على سبيل المثال: AppSettings: Parameter1.
في ملف Startup.cs ، أضف:
public void ConfigureServices(IServiceCollection services)
{
// "Parameter1" ServiceABC
var settingsParameter1 = Configuration["AppSettings:Parameter1"];
// "Parameter1"
services.AddScoped(s=> new ServiceABC(settingsParameter1));
//next
services.AddControllersWithViews();
}
مثال على استخدام خدمة ServiceABC في وحدة تحكم ، سيتم عرض قيمة Parameter1 في صفحة html.
لاستخدام الخدمة في وحدات التحكم ، قم بإضافتها إلى المُنشئ ، ملف HomeController.cs
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly ServiceABC _serviceABC;
public HomeController(ILogger<HomeController> logger, ServiceABC serviceABC)
{
_logger = logger;
_serviceABC = serviceABC;
}
public IActionResult Index()
{
return View(_serviceABC);
}
إضافة ملف ServiceABC للرؤية _ViewImports.cshtml
@using ConfigurationTemplate_1.Services
قم بتغيير Index.cshtml لعرض صفحة خيارات Parameter1 .
@model ServiceABC
@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1> ASP.NET Core</h1>
<h4> </h4>
</div>
<div>
<p> ServiceABC,
Parameter1 = @Model.Title</p>
</div>
لنبدأ التطبيق:
النتيجة
هذا النهج يحل المشكلة جزئيًا. لا يسمح هذا الحل بتطبيق تغييرات التكوين أثناء تشغيل التطبيق. تتلقى الخدمة قيمة ملف التكوين فقط عند بدء التشغيل ، ثم تعمل فقط مع هذا المثيل. نتيجة لذلك ، لن تؤدي التغييرات اللاحقة على ملف التكوين إلى تغييرات في التطبيق.
باستخدام IConfiguration مثل Singleton
GitHub: ConfigurationTemplate_2
الخيار الثاني هو وضع IConfiguration (مثل Singleton) في الخدمات. نتيجة لذلك ، يمكن استدعاء تكوين الرمز من وحدات التحكم والخدمات الأخرى. عند استخدام AddSingleton ، يتم إنشاء الخدمة مرة واحدة ، وعند استخدام التطبيق ، تنتقل المكالمة إلى نفس الحالة. استخدم هذه الطريقة بحذر شديد ، حيث يمكن أن تحدث مشاكل تسرب الذاكرة وتعدد مؤشرات الترابط.
دعنا نستبدل الكود من المثال السابق في Startup.cs بآخر جديد ، حيث
services.AddSingleton<IConfiguration>(Configuration);يضيف IConfiguration مثل Singleton للخدمات.
public void ConfigureServices(IServiceCollection services)
{
// IConfiguration
services.AddSingleton<IConfiguration>(Configuration);
// "ServiceABC"
services.AddScoped<ServiceABC>();
//next
services.AddControllersWithViews();
}
قم بتغيير مُنشئ خدمة ServiceABC لقبول تكوين IConfiguration
public class ServiceABC
{
private readonly IConfiguration _configuration;
public string Title => _configuration["AppSettings:Parameter1"];
public ServiceABC(IConfiguration Configuration)
{
_configuration = Configuration;
}
public ServiceABC()
{ }
}
كما في الإصدار السابق ، أضف الخدمة إلى المنشئ وأضف رابطًا إلى مساحة الاسم
, HomeController.cs
ServiceABC _ViewImports.cshtml:
Index.cshtml Parameter1 .
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly ServiceABC _serviceABC;
public HomeController(ILogger<HomeController> logger, ServiceABC serviceABC)
{
_logger = logger;
_serviceABC = serviceABC;
}
public IActionResult Index()
{
return View(_serviceABC);
}
ServiceABC _ViewImports.cshtml:
@using ConfigurationTemplate_2.Services;
Index.cshtml Parameter1 .
@model ServiceABC
@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1> ASP.NET Core</h1>
<h4> IConfiguration Singleton</h4>
</div>
<div>
<p>
ServiceABC,
Parameter1 = @Model.Title
</p>
</div>
دعونا تبدأ التطبيق:
و ServiceABC خدمة تضاف إلى الحاوية باستخدام وسائل AddScoped أن مثيل الطبقة سيتم إنشاؤها على كل طلب الصفحة. نتيجة لذلك ، سيتم إنشاء مثيل لفئة ServiceABC في كل طلب http مع إعادة تحميل تكوين تكوين IConfiguration ، وسيتم تطبيق التغييرات الجديدة على appsettings.json.
وبالتالي ، إذا أثناء تشغيل التطبيق ، قم بتغيير معلمة Parameter1 إلى "NEW !!! Parameter1 ABC "، في المرة التالية التي تدخل فيها إلى صفحة البداية ، سيتم عرض قيمة المعلمة الجديدة.
لنقم بتحديث الصفحة بعد تغيير ملف appsettings.json :
النتيجة
عيب هذا النهج هو القراءة اليدوية لكل معلمة. وإذا أضفت التحقق من صحة المعلمة ، فلن يتم إجراء الفحص بعد تغيير ملف appsettings.json ، ولكن في كل مرة تستخدم فيها ServiceABC ، وهو إجراء غير ضروري. في أفضل الأحوال ، يجب التحقق من صحة المعلمات مرة واحدة فقط بعد كل تغيير في الملف.
إلغاء تسلسل التكوين مع التحقق من الصحة (خيار IOptions)
GitHub: ConfigurationTemplate_3
اقرأ عن الخيارات هنا . يلغي
هذا الخيار الحاجة إلى استخدام ServiceABC . بدلاً من ذلك ، يتم استخدام فئة AppSettings ، والتي تحتوي على الإعدادات من ملف التكوين وكائن ClientConfig . يحتاج كائن ClientConfig إلى التهيئة بعد تغيير التكوين ، لأن يتم استخدام كائن جاهز في وحدات التحكم.
ClientConfig هي فئة تتفاعل مع أنظمة خارجية ، ولا يمكن تغيير رمزها. إذا قمت بإلغاء تسلسل بيانات فئة AppSettings فقط ، فسيكون ClientConfigستكون فارغة. لذلك ، من الضروري الاشتراك في حدث تكوين القراءة وتهيئة كائن ClientConfig في المعالج .
لنقل التكوين ليس في شكل أزواج مفتاح-قيمة ، ولكن ككائنات من فئات معينة ، سنستخدم واجهة IOptions . بالإضافة إلى ذلك ، يسمح لك IOptions ، بخلاف ConfigurationManager ، بإلغاء تسلسل الأقسام الفردية. لإنشاء كائن ClientConfig ، ستحتاج إلى استخدام IPostConfigureOptions ، والذي يتم تنفيذه بعد معالجة جميع التكوينات. سيتم تنفيذ IPostConfigureOptions في كل مرة تتم فيها قراءة التكوين مؤخرًا.
لنقم بإنشاء ClientConfig.cs :
public class ClientConfig
{
private string _parameter1;
private string _parameter2;
public string Value => _parameter1 + " " + _parameter2;
public ClientConfig(ClientConfigOptions configOptions)
{
_parameter1 = configOptions.Parameter1;
_parameter2 = configOptions.Parameter2;
}
}
سوف يأخذ المعلمات كمنشئ في شكل كائن ClientConfigOptions :
public class ClientConfigOptions
{
public string Parameter1;
public string Parameter2;
}
دعونا ننشئ فئة إعدادات AppSettings ، ونحدد طريقة ClientConfigBuild () فيها ، والتي ستنشئ كائن ClientConfig .
ملف AppSettings.cs :
public class AppSettings
{
public string Parameter1 { get; set; }
public string Parameter2 { get; set; }
public ClientConfig clientConfig;
public void ClientConfigBuild()
{
clientConfig = new ClientConfig(new ClientConfigOptions()
{
Parameter1 = this.Parameter1,
Parameter2 = this.Parameter2
}
);
}
}
لنقم بإنشاء معالج تكوين ستتم معالجته أخيرًا. للقيام بذلك ، يجب أن تكون موروثة من IPostConfigureOptions . ستقوم آخر PostConfigure بتنفيذ ClientConfigBuild () ، والذي سينشئ ClientConfig .
ملف ConfigureAppSettingsOptions.cs :
public class ConfigureAppSettingsOptions: IPostConfigureOptions<AppSettings>
{
public ConfigureAppSettingsOptions()
{ }
public void PostConfigure(string name, AppSettings options)
{
options.ClientConfigBuild();
}
}
الآن يبقى إجراء تغييرات فقط في Startup.cs ، ستؤثر التغييرات فقط على وظيفة ConfigureServices (خدمات IServiceCollection) .
أولاً ، دعنا نقرأ قسم AppSettings في appsettings.json
// configure strongly typed settings objects
var appSettingsSection = Configuration.GetSection("AppSettings");
services.Configure<AppSettings>(appSettingsSection);
علاوة على ذلك ، لكل طلب ، سيتم إنشاء نسخة من AppSettings لإمكانية الاتصال بعد المعالجة:
services.AddScoped(sp => sp.GetService<IOptionsSnapshot<AppSettings>>().Value);
دعنا نضيف معالجة لاحقة لفئة AppSettings كخدمة:
services.AddSingleton<IPostConfigureOptions<AppSettings>, ConfigureAppSettingsOptions>();
تمت إضافة رمز إلى Startup.cs
public void ConfigureServices(IServiceCollection services)
{
// configure strongly typed settings objects
var appSettingsSection = Configuration.GetSection("AppSettings");
services.Configure<AppSettings>(appSettingsSection);
services.AddScoped(sp => sp.GetService<IOptionsSnapshot<AppSettings>>().Value);
services.AddSingleton<IPostConfigureOptions<AppSettings>, ConfigureAppSettingsOptions>();
//next
services.AddControllersWithViews();
}
للوصول إلى التكوين ، سيكون كافيًا حقن AppSettings من وحدة التحكم .
ملف HomeController.cs :
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly AppSettings _appSettings;
public HomeController(ILogger<HomeController> logger, AppSettings appSettings)
{
_logger = logger;
_appSettings = appSettings;
}
دعنا نغير Index.cshtml لعرض معلمة القيمة لكائن lientConfig
@model AppSettings
@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1> ASP.NET Core</h1>
<h4> ( IOptions)</h4>
</div>
<div>
<p>
ClientConfig,
= @Model.clientConfig.Value
</p>
</div>
لنبدأ التطبيق: إذا أثناء تشغيل التطبيق ، قم بتغيير معلمة Parameter1 إلى "NEW !!! المعلمة 1 ABC " والمعلمة 2 إلى" جديد !!! Parameter2 ABC "، في المرة التالية التي تصل فيها إلى الصفحة الأولية ، سيتم عرض خاصية القيمة الجديدة :
النتيجة
يسمح لك هذا الأسلوب بإلغاء تسلسل كافة قيم التكوين دون تكرار المعلمات يدويًا. يعمل كل طلب http مع مثيله الخاص من AppSettings و lientConfig ، مما يلغي حالة التصادمات. يضمن IPostConfigureOptions أن يتم تنفيذه أخيرًا عند إعادة قراءة جميع الخيارات. عيب هذا الحل هو الإنشاء المستمر لمثيل ClientConfig لكل طلب ، وهو أمر غير عملي لأن في الواقع ، يجب إعادة إنشاء ClientConfig فقط بعد تغييرات التكوين.
إلغاء تسلسل التكوين مع التحقق (بدون استخدام IOptions)
GitHub: طريقة استخدام ConfigurationTemplate_4
باستخدام IPostConfigureOptions تؤدي إلى إنشاء كائن ClientConfig في كل مرة تتلقى طلبًا من العميل. هذا ليس عقلاني بما فيه الكفاية لأن يعمل كل طلب مع حالة ClientConfig أولية ، والتي لا تتغير إلا عند تغيير ملف التكوين appsettings.json. للقيام بذلك ، سوف نتخلى عن IPostConfigureOptions وننشئ معالج التكوين الذي سيتم استدعاؤه فقط عندما يتغير appsettings.json ، ونتيجة لذلك سيتم إنشاء ClientConfig مرة واحدة فقط ، وبعد ذلك سيتم منح مثيل ClientConfig الذي تم إنشاؤه بالفعل لكل طلب.
قم بإنشاء فئة SingletonAppSettingsالتكوين (Singleton) الذي سيتم من خلاله إنشاء مثيل من الإعدادات لكل طلب.
ملف SingletonAppSettings.cs :
public class SingletonAppSettings
{
public AppSettings appSettings;
private static readonly Lazy<SingletonAppSettings> lazy = new Lazy<SingletonAppSettings>(() => new SingletonAppSettings());
private SingletonAppSettings()
{ }
public static SingletonAppSettings Instance => lazy.Value;
}
دعنا نعود إلى فئة بدء التشغيل ونضيف مرجعًا إلى واجهة IServiceCollection .
سيتم استخدامه في طريقة معالجة التكوين
public IServiceCollection Services { get; set; }
لنقم بتغيير ConfigureServices (خدمات IServiceCollection) ونمرر مرجعًا إلى IServiceCollection .
ملف Startup.cs :
public void ConfigureServices(IServiceCollection services)
{
Services = services;
// AppSettings
var appSettings = Configuration.GetSection("AppSettings").Get<AppSettings>();
appSettings.ClientConfigBuild();
لنقم بإنشاء تكوين Singleton وإضافته إلى مجموعة الخدمات:
SingletonAppSettings singletonAppSettings = SingletonAppSettings.Instance;
singletonAppSettings.appSettings = appSettings;
services.AddSingleton(singletonAppSettings);
دعنا نضيف كائن AppSettings كنطاق ، مع كل طلب ، سيتم إنشاء نسخة من Singleton:
services.AddScoped(sp => sp.GetService<SingletonAppSettings>().appSettings);
تكوين الخدمات بالكامل (خدمات IServiceCollection) :
public void ConfigureServices(IServiceCollection services)
{
Services = services;
// AppSettings
var appSettings = Configuration.GetSection("AppSettings").Get<AppSettings>();
appSettings.ClientConfigBuild();
SingletonAppSettings singletonAppSettings = SingletonAppSettings.Instance;
singletonAppSettings.appSettings = appSettings;
services.AddSingleton(singletonAppSettings);
services.AddScoped(sp => sp.GetService<SingletonAppSettings>().appSettings);
//next
services.AddControllersWithViews();
}
أضف الآن معالجًا للتكوين في Configure (تطبيق IApplicationBuilder ، IWebHostEnvironment env) . يتم استخدام رمز مميز لتتبع التغيير في ملف appsettings.json. OnChange هي الوظيفة التي يجب استدعاؤها عند تغيير الملف. معالج تكوين OnChange () :
ChangeToken.OnChange(() => Configuration.GetReloadToken(), onChange);
أولاً ، نقرأ ملف appsettings.json وقمنا بإلغاء تسلسل فئة AppSettings . ثم ، من مجموعة الخدمات ، نحصل على مرجع إلى Singleton الذي يخزن كائن AppSettings ، واستبدله بآخر جديد.
private void onChange()
{
var newAppSettings = Configuration.GetSection("AppSettings").Get<AppSettings>();
newAppSettings.ClientConfigBuild();
var serviceAppSettings = Services.BuildServiceProvider().GetService<SingletonAppSettings>();
serviceAppSettings.appSettings = newAppSettings;
Console.WriteLine($"AppSettings has been changed! {DateTime.Now}");
}
في HomeController ، سنقوم بحقن رابط إلى AppSettings ، كما في الإصدار السابق (ConfigurationTemplate_3)
HomeController.cs:
Index.cshtml Value lientConfig:
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly AppSettings _appSettings;
public HomeController(ILogger<HomeController> logger, AppSettings appSettings)
{
_logger = logger;
_appSettings = appSettings;
}
Index.cshtml Value lientConfig:
@model AppSettings
@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1> ASP.NET Core</h1>
<h4> ( IOptions)</h4>
</div>
<div>
<p>
ClientConfig,
= @Model.clientConfig.Value
</p>
</div>
لنبدأ التطبيق:
بعد تحديد وضع التشغيل كتطبيق وحدة تحكم ، في نافذة التطبيق ، يمكنك رؤية رسالة حول بدء حدث تغيير ملف التكوين
:
النتيجة
هذا الخيار أفضل من استخدام IPostConfigureOptions لأن يسمح لك ببناء كائن فقط بعد تغيير ملف التكوين ، وليس عند كل طلب. والنتيجة هي تقليل وقت استجابة الخادم. بعد تشغيل الرمز المميز ، تتم إعادة تعيين حالة الرمز المميز.
إضافة الإعدادات الافتراضية والتحقق من صحة التكوين
GitHub: ConfigurationTemplate_5
في الأمثلة السابقة ، إذا كان ملف appsettings.json مفقودًا ، فسيقوم التطبيق بطرح استثناء ، لذلك دعونا نجعل ملف التكوين اختياريًا ونضيف الإعدادات الافتراضية. عند نشر تطبيق مشروع تم إنشاؤه من قالب في Visula Studio ، سيكون ملف appsettings.json موجودًا في نفس المجلد مع جميع الثنائيات ، وهو أمر غير مريح عند النشر في Docker. تم نقل ملف appsettings.json إلى config / :
.AddJsonFile("config/appsettings.json")
لتتمكن من تشغيل التطبيق بدون appsettings.json ، قم بتغيير معلمة optiona l إلى true ، والتي تعني في هذه الحالة أن appsettings.json اختيارية.
ملف Startup.cs :
public Startup(IConfiguration configuration)
{
var builder = new ConfigurationBuilder()
.AddJsonFile("config/appsettings.json", optional: true, reloadOnChange: true);
configuration = builder.Build();
Configuration = configuration;
}
أضف إلى ConfigureServices (IServiceCollection services) الفراغ العام إلى سطر إلغاء تسلسل التكوين حالة معالجة عدم وجود ملف appsettings.json:
var appSettings = Configuration.GetSection("AppSettings").Get<AppSettings>() ?? new AppSettings();
دعنا نضيف التحقق من صحة التكوين على أساس واجهة IValidatableObject . إذا كانت معلمات التكوين مفقودة ، فسيتم استخدام القيمة الافتراضية.
دعونا نرث فئة AppSettings من IValidatableObject وننفذ الطريقة:
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
ملف AppSettings.cs :
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
List<ValidationResult> errors = new List<ValidationResult>();
if (string.IsNullOrWhiteSpace(this.Parameter1))
{
errors.Add(new ValidationResult(" Parameter1. " +
" DefaultParameter1 ABC"));
this.Parameter1 = "DefaultParameter1 ABC";
}
if (string.IsNullOrWhiteSpace(this.Parameter2))
{
errors.Add(new ValidationResult(" Parameter2. " +
" DefaultParameter2 ABC"));
this.Parameter2 = "DefaultParameter2 ABC";
}
return errors;
}
أضف طريقة لاستدعاء فحص التكوين ليتم استدعاؤه من ملف Startup.cs فئة بدء التشغيل :
private void ValidateAppSettings(AppSettings appSettings)
{
var resultsValidation = new List<ValidationResult>();
var context = new ValidationContext(appSettings);
if (!Validator.TryValidateObject(appSettings, context, resultsValidation, true))
{
resultsValidation.ForEach(
error => Console.WriteLine($" : {error.ErrorMessage}"));
}
}
دعنا نضيف استدعاء لطريقة التحقق من صحة التكوين في ConfigureServices (خدمات IServiceCollection). إذا لم يكن هناك ملف appsettings.json ، فأنت بحاجة إلى تهيئة كائن AppSettings بالقيم الافتراضية.
ملف Startup.cs :
var appSettings = Configuration.GetSection("AppSettings").Get<AppSettings>() ?? new AppSettings();
فحص المعلمة. إذا تم استخدام القيمة الافتراضية ، سيتم عرض رسالة تشير إلى المعلمة في وحدة التحكم.
//Validate
this.ValidateAppSettings(appSettings);
appSettings.ClientConfigBuild();
دعونا نغير إعدادات التحقق في onChange ()
private void onChange()
{
var newAppSettings = Configuration.GetSection("AppSettings").Get<AppSettings>() ?? new AppSettings();
//Validate
this.ValidateAppSettings(newAppSettings);
newAppSettings.ClientConfigBuild();
var serviceAppSettings = Services.BuildServiceProvider().GetService<SingletonAppSettings>();
serviceAppSettings.appSettings = newAppSettings;
Console.WriteLine($"AppSettings has been changed! {DateTime.Now}");
}
إذا قمت بحذف مفتاح Parameter1 من ملف appsettings.json ، فبعد حفظ الملف ، ستظهر رسالة حول غياب المعلمة في نافذة تطبيق وحدة التحكم:
النتيجة
يعد تغيير مسار موقع التكوينات في مجلد التكوين حلاً جيدًا. يسمح لك بعدم خلط جميع الملفات في كومة واحدة. يتم تحديد مجلد التكوين فقط لتخزين ملفات التكوين. تبسيط مهمة نشر التطبيق وتكوينه للمسؤولين من خلال التحقق من صحة التكوين. إذا أضفت ناتج أخطاء التكوين إلى السجل ، فسيتلقى المسؤول ، إذا تم تحديد معلمات غير صحيحة ، معلومات دقيقة حول المشكلة ، وليس كما بدأ المبرمجون مؤخرًا في الكتابة إلى أي استثناء: "حدث خطأ ما" .
لا يوجد خيار مثالي للعمل مع التكوين ، كل هذا يتوقف على المهمة المطروحة ، كل خيار له إيجابياته وسلبياته.
جميع قوالب التكوين متوفرة هنا .
الأدب:
- تصحيح ASP.NET Core
- METANIT - التكوين. أساسيات التكوين
- نمط تصميم فردي C #
- إعادة التكوين في .NET core
- إعادة تحميل الخيارات المكتوبة بقوة عند تغيير الملف في ASP.NET Core RC2
- تكوين تطبيق ASP.NET Core عبر IOptions
- METANIT - تمرير التكوين عبر IOptions
- تكوين تطبيق ASP.NET Core عبر IOptions
- METANIT - نموذج التحقق الذاتي