builder.Services.Configure<TopItemSettings>(TopItemSettings.Month,
builder.Configuration.GetSection("TopItem:Month"));
builder.Services.Configure<TopItemSettings>(TopItemSettings.Year,
builder.Configuration.GetSection("TopItem:Year"));
اینجا دو Named Options میسازیم:
TopItemSettings.Month
TopItemSettings.Year
استفاده از Named Options با IOptionsSnapshot 🔍📦
public class TestNOModel : PageModel
{
private readonly TopItemSettings _monthTopItem;
private readonly TopItemSettings _yearTopItem;
public TestNOModel(IOptionsSnapshot<TopItemSettings> namedOptionsAccessor)
{
_monthTopItem = namedOptionsAccessor.Get(TopItemSettings.Month);
_yearTopItem = namedOptionsAccessor.Get(TopItemSettings.Year);
}
public ContentResult OnGet()
{
return Content($"Month:Name {_monthTopItem.Name} \n" +
$"Month:Model {_monthTopItem.Model} \n\n" +
$"Year:Name {_yearTopItem.Name} \n" +
$"Year:Model {_yearTopItem.Model} \n");
}
}
در کد بالا:
• ءSnapshot مربوط به Month گرفته میشود.
• ءSnapshot مربوط به Year گرفته میشود.
توضیح ساختار Options و NamedOptions 🧩
🔸️تمام Options در واقع Named Instance هستند.
🔹️ء<IConfigureOptions<T> برای Default Name اعمال میشود، یعنی نام خالی ("").
🔸️ء<IConfigureNamedOptions<T علاوهبر آنکه IConfigureOptions را هم پیادهسازی میکند، برای Named Options مخصوص استفاده میشود.
🔹️در <IOptionsFactory<TOptions منطق انتخاب نام وجود دارد:
🔸️اگر نام Null باشد یعنی Configure روی همهٔ Named Options اعمال میشود.
🔹️متدهای ConfigureAll و PostConfigureAll از همین رفتار استفاده میکنند.
این باعث میشود بتوانید:
• یک پیکربندی خاص را برای یک نام خاص تنظیم کنید.
• و یک پیکربندی کلی را برای همه نامها اعمال کنید.
OptionsBuilder API 🏗✨
چرا OptionsBuilder؟
ء<OptionsBuilder<TOptions فرایند ساخت Named Options را سادهتر میکند چون:
تنها در یک جای اولیه نام option مشخص میشود:
services.AddOptions<TOptions>("MyName")اما در بقیهٔ متدهای Configure نیازی نیست نام را تکرار کنید.
ءValidation Options فقط با OptionsBuilder قابل انجام است.
متدهایی که Service Dependency دریافت میکنند نیز فقط با OptionsBuilder پشتیبانی میشوند.
نمونهٔ استفاده
در بخش Options Validation به کار میرود.
استفاده از سرویسهای DI برای پیکربندی Options ⚙️📦
سرویسها را میتوان هنگام پیکربندی options به دو روش از dependency injection دریافت کرد:
ارسال یک configuration delegate به متد Configure روی <OptionsBuilder<TOptions.
ء<OptionsBuilder<TOptions چندین overload از Configure ارائه میدهد که اجازه میدهد تا حداکثر پنج سرویس برای پیکربندی options استفاده شوند:
builder.Services.AddOptions<MyOptions>("optionalName")
.Configure<Service1, Service2, Service3, Service4, Service5>(
(o, s, s2, s3, s4, s5) =>
o.Property = DoSomethingWith(s, s2, s3, s4, s5));ایجاد یک نوع (class) که <IConfigureOptions<TOptions یا <IConfigureNamedOptions<TOptions را پیادهسازی کند و ثبت آن بهعنوان سرویس.
توصیه میشود از روش ارسال configuration delegate به Configure استفاده کنید، زیرا ایجاد یک سرویس پیچیدهتر است. ایجاد نوع دقیقاً معادل کاری است که فریمورک هنگام فراخوانی Configure انجام میدهد.
فراخوانی Configure یک سرویس transient از نوع generic IConfigureNamedOptions<TOptions ثبت میکند که دارای سازندهای است که سرویسهای generic مشخصشده را میپذیرد.