ءBind و مقداردهی برای کلاس abstract🔧
ءBind اجازه میدهد که یک کلاس abstract مقداردهی شود.
کد زیر از کلاس abstract زیر استفاده میکند:
namespace ConfigSample.Options;
public abstract class SomethingWithAName
{
public abstract string? Name { get; set; }
}
public class NameTitleOptions(int age) : SomethingWithAName
{
public const string NameTitle = "NameTitle";
public override string? Name { get; set; }
public string Title { get; set; } = string.Empty;
public int Age { get; set; } = age;
}
کد زیر مقداردهی NameTitleOptions را نمایش میدهد:
public class Test33Model : PageModel
{
private readonly IConfiguration Configuration;
public Test33Model(IConfiguration configuration)
{
Configuration = configuration;
}
public ContentResult OnGet()
{
var nameTitleOptions = new NameTitleOptions(22);
Configuration.GetSection(NameTitleOptions.NameTitle).Bind(nameTitleOptions);
return Content($"Title: {nameTitleOptions.Title} \n" +
$"Name: {nameTitleOptions.Name} \n" +
$"Age: {nameTitleOptions.Age}"
);
}
}
تفاوت Bind و Get ⚖️
Bind:
• امکان مقداردهی یک کلاس abstract را میدهد.
• نیازی به ساخت instance ندارد.
Get<>:
• باید خودش یک instance بسازد.
• بنابراین فقط روی انواع concrete کار میکند.
Options Pattern🔖
روش دیگر هنگام استفاده از Options Pattern این است که سکشن Position را Bind کرده و آن را به Service Container اضافه کنیم.
کد زیر، کلاس PositionOptions را با Configure به DI اضافه میکند:
using ConfigSample.Options;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.Configure<PositionOptions>(
builder.Configuration.GetSection(PositionOptions.Position));
var app = builder.Build();
اکنون میتوانیم از طریق DI تنظیمات را بخوانیم:
public class Test2Model : PageModel
{
private readonly PositionOptions _options;
public Test2Model(IOptions<PositionOptions> options)
{
_options = options.Value;
}
public ContentResult OnGet()
{
return Content($"Title: {_options.Title} \n" +
$"Name: {_options.Name}");
}
}
در این روش، تغییرات فایل JSON بعد از شروع برنامه خوانده نمیشوند.
برای پشتیبانی از تغییرات runtime باید از IOptionsSnapshot استفاده کنید. 🔄
Options Interfaces 🔍
1️⃣ IOptions<TOptions>
پشتیبانی نمیکند از:
• خواندن تغییرات configuration بعد از start
• ءNamed options
• ءSingleton است → در تمام طول برنامه ثابت است.
• میتواند در هر service lifetime inject شود.
2️⃣ IOptionsSnapshot<TOptions>
• در سناریوهایی مفید است که تنظیمات باید در هر درخواست مجدداً محاسبه شوند.
• ءScoped است → نمیتوان آن را در یک Singleton inject کرد.
• از Named options پشتیبانی میکند.
• برای خواندن تغییرات Runtime مناسب است. 🔁
3️⃣ IOptionsMonitor<TOptions>
• برای دریافت options و مدیریت Change Notification استفاده میشود.
• ءSingleton است.
پشتیبانی میکند از:
• Reloadable configuration
• Named options
• Selective invalidation (با IOptionsMonitorCache)
4️⃣ IOptionsFactory<TOptions>
مسئول ایجاد instanceهای جدید گزینههاست.
پیکربندیها را (IConfigureOptions و IPostConfigureOptions) اجرا میکند.
5️⃣ IOptionsMonitorCache<TOptions>
• کش داخلی IOptionsMonitor
• میتواند یک گزینه را حذف کند تا مقدار جدید دوباره محاسبه شود.
• امکان اضافهکردن دستی مقدار جدید با TryAdd
• متد Clear برای ریست تمام named options