‫ذخیره سازی تنظیمات برنامه‌های ASP.NET Core در بانک اطلاعاتی به کمک Entity Framework Core

دسته‌بندی: آموزش
تاریخ انتشار: ۱۳۹۸ فروردین ۱۸, یکشنبه ساعت ۱۲:۴۶۰ رأیبدون امتیاز

در مطلب «ارتقاء به ASP.NET Core 1.0 – قسمت 7 – کار با فایل‌های config » با مقدمات کار با فایل‌های تنظیمات برنامه و تامین کننده‌های مختلف آن‌ها آشنا شدیم. در این مطلب قصد داریم یک نمونه‌ی سفارشی تامین کننده‌های تنظیمات برنامه را بر اساس دریافت و ذخیره سازی اطلاعات در بانک اطلاعاتی، تهیه کنیم.\ ساختار...

در مطلب «ارتقاء به ASP.NET Core 1.0 – قسمت ۷ – کار با فایل‌های config » با مقدمات کار با فایل‌های تنظیمات برنامه و تامین کننده‌های مختلف آن‌ها آشنا شدیم. در این مطلب قصد داریم یک نمونه‌ی سفارشی تامین کننده‌های تنظیمات برنامه را بر اساس دریافت و ذخیره سازی اطلاعات در بانک اطلاعاتی، تهیه کنیم.

ساختار موجودیت تنظیمات برنامه

تنظیمات برنامه با هر قالبی که تهیه شوند، دست آخر به صورت یک e.Key).HasMaxLength(450).IsRequired(); entity.HasIndex(e => e.Key).IsUnique(); entity.Property(e => e.Value).IsRequired(); entity.HasData(new ConfigurationValue { Id = 1, Key = "key-1", Value = "value_from_ef_1" }); entity.HasData(new ConfigurationValue { Id = 2, Key = "key-2", Value = "value_from_ef_2" }); }); }

ایجاد یک IConfigurationSource سفارشی مبتنی بر بانک اطلاعاتی

انواع و اقسام تامین کننده‌های تنظیمات برنامه در پروژه‌های ASP.NET Core، در حقیقت یک پیاده سازی سفارشی از اینترفیس IConfigurationSource هستند. به همین جهت در ادامه یک نمونه‌ی مبتنی بر EF Core آن را تهیه می‌کنیم:

public class EFConfigurationSource : IConfigurationSource { private readonly IServiceProvider _serviceProvider; public EFConfigurationSource(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; } public IConfigurationProvider Build(IConfigurationBuilder builder) { return new EFConfigurationProvider(_serviceProvider); } }

در اینجا چون می‌خواهیم به IUnitOfWork دسترسی پیدا کنیم، IServiceProvider را به سازنده‌ی این تامین کننده تزریق کرده‌ایم. کار اصلی ساخت آن نیز در متد Build، با ارائه‌ی یک IConfigurationProvider سفارشی انجام می‌شود. اینجا است که اطلاعات را از بانک اطلاعاتی خوانده و در اختیار سیستم تنظیمات برنامه قرار می‌دهیم:

public class EFConfigurationProvider : ConfigurationProvider { private readonly IServiceProvider _serviceProvider; public EFConfigurationProvider(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; ensureDatabaseIsCreated(); } public override void Load() { using (var scope = _serviceProvider.CreateScope()) { var uow = scope.ServiceProvider.GetRequiredService(); this.Data?.Clear(); this.Data = uow.Set() .AsNoTracking() .ToList() .ToDictionary(c => c.Key, c => c.Value); } } private void ensureDatabaseIsCreated() { using (var scope = _serviceProvider.CreateScope()) { var uow = scope.ServiceProvider.GetRequiredService(); uow.Migrate(); } } }

در ConfigurationProvider فوق، متد Load، در آغاز برنامه فراخوانی شده و در اینجا فرصت داریم تا خاصیت this.Data آن‌را که از نوع { var minutes = (int)TimeSpan.FromMinutes(3).TotalSeconds; dbOptions.CommandTimeout(minutes); dbOptions.EnableRetryOnFailure(); }); }); var serviceProvider = services.BuildServiceProvider(); var configuration = new ConfigurationBuilder() .AddConfiguration(Configuration) // Adds all of the existing configurations .AddEFConfig(serviceProvider) .Build(); services.AddSingleton(sp => configuration); // Replace services.AddSingleton(sp => configuration); // Replace

در اینجا ابتدا نیاز است یک ConfigurationBuilder جدید را ایجاد کنیم تا بتوان AddEFConfig را بر روی آن فراخوانی کرد. در این بین، خود برنامه نیز تعدادی تامین کننده‌ی تنظیمات پیش‌فرض را نیز دارد که قصد نداریم سبب پاک شدن آن‌ها شویم. به همین جهت آن‌ها را توسط متد AddConfiguration، افزوده‌ایم. پس از تعریف این ConfigurationBuilder جدید، نیاز است آن‌را جایگزین IConfiguration و IConfigurationRoot پیش‌فرض برنامه کنیم که روش آن‌را در دو متد services.AddSingleton ملاحظه می‌کنید.

همچنین روش دسترسی به serviceProvider مورد نیاز AddEFConfig، توسط متد services.BuildServiceProvider نیز در کدهای فوق مشخص است. به همین جهت مجبور شدیم این تعریف را در اینجا قرار دهیم و گرنه می‌شد از کلاس Program و یا حتی سازنده‌ی کلاس Startup نیز استفاده کرد. مشکل این دو مکان عدم دسترسی به سرویس IUnitOfWork و سایر تنظیمات برنامه است.

آزمایش برنامه

اگر به قسمت «ساختار Context برنامه و مقدار دهی اولیه‌ی آن» مطلب جاری دقت کرده باشید، دو کلید پیش‌فرض در اینجا ثبت شده‌اند. به همین جهت در ادامه با تزریق سرویس IConfiguration به سازنده‌ی یک کنترلر، سعی در خواندن مقادیر آن‌ها خواهیم کرد:

namespace DbConfig.Web.Controllers { public class HomeController : Controller { private readonly IConfiguration _configuration; public HomeController(IConfiguration configuration) { _configuration = configuration; } public IActionResult Index() { return Json( new { key1 = _configuration["key-1"], key2 = _configuration["key-2"] }); }

با این خروجی:

به روز رسانی بانک اطلاعاتی برنامه و بارگذاری مجدد اطلاعات IConfiguration

فرض کنید توسط سرویسی، اطلاعات جدول ConfigurationValue را تغییر داده‌اید. نکته‌ی مهم اینجا است که اینکار سبب فراخوانی مجدد متد Load کلاس EFConfigurationProvider نخواهد شد و عملا این تغییرات در سراسر برنامه توسط تزریق اینترفیس IConfiguration قابل دسترسی نخواهند بود (مگر اینکه برنامه مجددا ری‌استارت شود). نکته‌ی به روز رسانی این اطلاعات به صورت زیر است:

public class ConfigurationValuesService : IConfigurationValuesService { private readonly IConfiguration _configuration; public ConfigurationValuesService(IConfiguration configuration) { _configuration = configuration; } private void reloadEFConfigurationProvider() { ((IConfigurationRoot)_configuration).Reload(); }

در جائیکه نیاز است پس از به روز رسانی بانک اطلاعاتی، تنظیمات برنامه را نیز بارگذاری مجدد کنید، ابتدا اینترفیس IConfiguration را به سازنده‌ی آن تزریق کرده و سپس به نحو فوق، متد Reload را فراخوانی کنید. اینکار سبب می‌شود تا یکبار دیگری متد Load کلاس EFConfigurationProvider نیز فراخوانی شود که باعث بارگذاری مجدد تنظیمات برنامه خواهد شد.

کدهای کامل این مطلب را از اینجا می‌توانید دریافت کنید: EFCoreDbConfig.zip

dotnettips

مطالب پیشنهادی

‫پَرباد – آموزش پیاده‌سازی پرداخت آنلاین در دات نت – مقدمه
‫ساخت کتابخانه‌های عمومی جاوا اسکریپتی توسط Angular CLI
‫آموزش تنظیمات CORS در ASP.NET Core
‫چک لیست شروع به ساخت یک نرم افزار بزرگ یا متوسط
اعتبارسنجی درخواست‌ها در ASP.NET Core چه خواهد شد؟
‫رمزنگاری خودکار فیلدها توسط Entity Framework Core
‫مروری بر Blazor (قسمت اول)
آموزش مقدماتی پایتون با Anaconda
ساخت اپلیکیشن های بدون سرور با زامارین و Azure
ساخت اپلیکیشن با انگولار و ASP.NET Web API
اشتراک‌گذاری

این مطلب برای شما مفید بود؟

بازخورد شما به بهبود کیفیت مطالب کمک می‌کند.

در حال بررسی رأی شما...