Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bağımlılık enjeksiyonu sayesinde, hizmetlerinizi ve bunlara ait yapılandırmaları kaydetmek için options pattern kullanılabilir. Seçenekler düzeni, kitaplığınızın (ve hizmetlerinizin) tüketicilerinin seçenekler sınıfınız olan TOptions örneklerini gerektirmesini sağlar. Yapılandırma seçeneklerini güçlü türdeki nesneler aracılığıyla tüketmek, tutarlı değer gösterimi sağlamaya yardımcı olur, veri ek açıklamalarıyla doğrulamayı mümkün kılar ve dize değerlerini elle ayrıştırma yükünü ortadan kaldırır. Kitaplığınızın tüketicilerinin kullanabileceği birçok yapılandırma sağlayıcısı vardır. Bu sağlayıcılarla tüketiciler kitaplığınızı birçok yolla yapılandırabilir.
Bir .NET kitaplığı yazarı olarak, seçenekler desenini kitaplığınızın tüketicilerine doğru şekilde gösterme hakkında genel yönergeleri öğreneceksiniz. Aynı şeyi başarmanın çeşitli yolları ve dikkat edilmesi gereken birkaç nokta vardır.
Adlandırma kuralları
Kural gereği, hizmetleri kaydetmekle sorumlu uzantı yöntemleri olarak adlandırılır Add{Service}; burada {Service} anlamlı ve açıklayıcı bir addır.
Add{Service} uzantı yöntemleri hem ASP.NET Core hem de .NET'te yaygındır.
✔️ Hizmetinizi diğer hizmetlerden ayıran adları düşünün.
❌ Resmi Microsoft paketlerinden .NET ekosisteminin parçası olan adları KULLANMAYIN.
✔️ Uzantı yöntemlerini kullanıma sunan statik sınıfları olarak {Type}Extensionsadlandırmayı düşünün. Burada {Type} , genişlettiğiniz türdür.
Namespace rehberi
Microsoft paketleri, çeşitli hizmet tekliflerinin kaydını birleştirmek için Microsoft.Extensions.DependencyInjection ad alanını kullanır.
✔️ Paket teklifinizi net bir şekilde tanımlayan bir ad alanı DÜŞÜNÜN.
❌ Ad alanını Microsoft.Extensions.DependencyInjection resmi olmayan Microsoft paketleri için KULLANMAYIN.
Parametresiz
Hizmetiniz çok az açık yapılandırmayla çalışabiliyorsa veya hiç açık yapılandırmayla çalışamıyorsa parametresiz bir uzantı yöntemi kullanmayı göz önünde bulundurun.
using Microsoft.Extensions.DependencyInjection;
namespace ExampleLibrary.Extensions.DependencyInjection;
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddMyLibraryService(
this IServiceCollection services)
{
services.AddOptions<LibraryOptions>()
.Configure(options =>
{
// Specify default option values
});
// Register lib services here...
// services.AddScoped<ILibraryService, DefaultLibraryService>();
return services;
}
}
Yukarıdaki kodda, :AddMyLibraryService
- IServiceCollection örneğini genişletir
-
OptionsServiceCollectionExtensions.AddOptions<TOptions>(IServiceCollection),
LibraryOptionstür parametresiyle çağrılır - Çağrıya Configure zincirler, bu da varsayılan seçenek değerlerini belirtir.
IConfiguration parametresi
Birçok seçeneği tüketicilere sunan bir kitaplık yazarken, bir IConfiguration parametre uzantısı yöntemi gerektirmeyi düşünebilirsiniz. Beklenen IConfiguration örneği, IConfiguration.GetSection işlevi kullanılarak yapılandırmanın adlandırılmış bir bölümüne atanmalıdır.
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace ExampleLibrary.Extensions.DependencyInjection;
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddMyLibraryService(
this IServiceCollection services,
IConfiguration namedConfigurationSection)
{
// Default library options are overridden
// by bound configuration values.
services.Configure<LibraryOptions>(namedConfigurationSection);
// Register lib services here...
// services.AddScoped<ILibraryService, DefaultLibraryService>();
return services;
}
}
Tavsiye
Configure<TOptions>(IServiceCollection, IConfiguration) yöntemi NuGet paketinin Microsoft.Extensions.Options.ConfigurationExtensions bir parçasıdır.
Yukarıdaki kodda, :AddMyLibraryService
- IServiceCollection örneğini genişletir
- Parametre IConfiguration tanımlar
namedConfigurationSection -
Configure<TOptions>(IServiceCollection, IConfiguration) öğesindeki çağrılar,
LibraryOptions'in genel tür parametresini venamedConfigurationSectionörneğini geçirerek yapılandırmak için kullanılır.
Bu desendeki tüketiciler, adlandırılmış bölümün kapsamlı IConfiguration örneğini sağlar:
using ExampleLibrary.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddMyLibraryService(
builder.Configuration.GetSection("LibraryOptions"));
using IHost host = builder.Build();
// Application code should start here.
await host.RunAsync();
Çağrı .AddMyLibraryService türü üzerinde IServiceCollection yapılır.
Kitaplık yazarı olarak varsayılan değerlerin belirtilmesi size bağlı.
Uyarı
Yapılandırmayı bir seçenek örneğine bağlamak mümkündür. Ancak ad çakışması riski vardır ve bu da hatalara neden olur. Buna ek olarak, bu şekilde el ile bağlandığınızda, seçenek deseninizin tüketimini yalnızca bir kez okumakla sınırlandırırsınız. Bu tür tüketiciler IOptionsMonitor arabirimini kullanamayacağından, ayarlarda yapılan değişiklikler yeniden bağlanmaz.
services.AddOptions<LibraryOptions>()
.Configure<IConfiguration>(
(options, configuration) =>
configuration.GetSection("LibraryOptions").Bind(options));
Bunun yerine uzantı yöntemini kullanmanız BindConfiguration gerekir. Bu uzantı yöntemi, yapılandırmayı seçenekler örneğine bağlar ve yapılandırma bölümü için bir değişiklik belirteci kaynağı kaydeder. Bu, tüketicilerin IOptionsMonitor arabirimini kullanmasına olanak tanır.
Yapılandırma bölümü yol parametresi
Kitaplığınızı kullananlar, temel TOptions türünü bağlamak için yapılandırma bölümü yolunu belirtmek isteyebilir. Bu senaryoda, uzantı yönteminizde bir string parametre tanımlarsınız.
using Microsoft.Extensions.DependencyInjection;
namespace ExampleLibrary.Extensions.DependencyInjection;
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddMyLibraryService(
this IServiceCollection services,
string configSectionPath)
{
services.AddOptions<SupportOptions>()
.BindConfiguration(configSectionPath)
.ValidateDataAnnotations()
.ValidateOnStart();
// Register lib services here...
// services.AddScoped<ILibraryService, DefaultLibraryService>();
return services;
}
}
Yukarıdaki kodda, :AddMyLibraryService
- IServiceCollection örneğini genişletir
- Parametre
stringtanımlarconfigSectionPath - Aramalar:
-
AddOptions,
SupportOptionstürünün genel tür parametresini kullanarak -
BindConfiguration verilen
configSectionPathparametreyle - ValidateDataAnnotations veri etiketleme doğrulamasını etkinleştirmek için
- ValidateOnStart çalışma zamanında değil, başlangıçta doğrulamayı zorlamak için
-
AddOptions,
Sonraki örnekte, veri ek açıklaması doğrulamasını etkinleştirmek için Microsoft.Extensions.Options.DataAnnotations NuGet paketi kullanılır.
SupportOptions sınıfı aşağıdaki gibi tanımlanır:
using System.ComponentModel.DataAnnotations;
public sealed class SupportOptions
{
[Url]
public string? Url { get; set; }
[Required, EmailAddress]
public required string Email { get; set; }
[Required, DataType(DataType.PhoneNumber)]
public required string PhoneNumber { get; set; }
}
Aşağıdaki JSON appsettings.json dosyasının kullanıldığını düşünün:
{
"Support": {
"Url": "https://support.example.com",
"Email": "help@support.example.com",
"PhoneNumber": "+1(888)-SUPPORT"
}
}
Action<TOptions> parametresi
Kitaplığınızın tüketicileri, seçenekler sınıfınızın bir örneğini veren bir lambda ifadesi sağlamak isteyebilir. Bu senaryoda, uzantı yönteminizde bir Action<LibraryOptions> parametre tanımlarsınız.
using Microsoft.Extensions.DependencyInjection;
namespace ExampleLibrary.Extensions.DependencyInjection;
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddMyLibraryService(
this IServiceCollection services,
Action<LibraryOptions> configureOptions)
{
services.Configure(configureOptions);
// Register lib services here...
// services.AddScoped<ILibraryService, DefaultLibraryService>();
return services;
}
}
Yukarıdaki kodda, :AddMyLibraryService
- IServiceCollection örneğini genişletir
-
Action<T> parametresini
configureOptions,T'ninLibraryOptionsolduğu yer tanımlar -
Configure belirtilen
configureOptionseylemini çağırır
Bu desendeki tüketiciler, bir lambda ifadesi (veya Action<LibraryOptions> parametresini karşılayan bir temsilci) sağlar:
using ExampleLibrary.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddMyLibraryService(options =>
{
// User defined option values
// options.SomePropertyValue = ...
});
using IHost host = builder.Build();
// Application code should start here.
await host.RunAsync();
Seçenekler nesnesi parametresi
Kütüphanenizin kullanıcıları, gömülü ayarlar örneği sağlamayı tercih edebilir. Bu senaryoda, options nesnenizin LibraryOptionsörneğini alan bir uzantı yöntemini kullanıma sunarsınız.
using Microsoft.Extensions.DependencyInjection;
namespace ExampleLibrary.Extensions.DependencyInjection;
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddMyLibraryService(
this IServiceCollection services,
LibraryOptions userOptions)
{
services.AddOptions<LibraryOptions>()
.Configure(options =>
{
// Overwrite default option values
// with the user provided options.
// options.SomeValue = userOptions.SomeValue;
});
// Register lib services here...
// services.AddScoped<ILibraryService, DefaultLibraryService>();
return services;
}
}
Yukarıdaki kodda, :AddMyLibraryService
- IServiceCollection örneğini genişletir
-
OptionsServiceCollectionExtensions.AddOptions<TOptions>(IServiceCollection),
LibraryOptionstür parametresiyle çağrılır -
Configure'e bir çağrı zincirler, bu da verilen
userOptionsörneğinden geçersiz kılınabilecek varsayılan seçenek değerlerini belirtir.
Bu desen içindeki tüketiciler, istenen özellik değerlerini satır içinde tanımlayarak LibraryOptions sınıfının bir örneğini sağlar.
using ExampleLibrary.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddMyLibraryService(new LibraryOptions
{
// Specify option values
// SomePropertyValue = ...
});
using IHost host = builder.Build();
// Application code should start here.
await host.RunAsync();
Sonraki yapılandırma
Tüm yapılandırma seçeneği değerleri bağlandıktan veya belirtildikten sonra, yapılandırma sonrası işlevselliği kullanılabilir. Daha önce ayrıntılı olarak belirtilen aynı Action<TOptions> parametreyi kullanmayı seçebilirsiniz PostConfigure. Yapılandırma sonrası tüm .Configure çağrıların ardından çalıştırılır.
PostConfigure kullanmayı düşünmek isteyebileceğiniz birkaç neden vardır:
-
Yürütme sırası: Çağrılarda
.Configureayarlanan tüm yapılandırma değerlerini geçersiz kılabilirsiniz. - Doğrulama: Diğer tüm yapılandırmalar uygulandıktan sonra varsayılan değerlerin ayarlandığını doğrulayabilirsiniz.
using Microsoft.Extensions.DependencyInjection;
namespace ExampleLibrary.Extensions.DependencyInjection;
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddMyLibraryService(
this IServiceCollection services,
Action<LibraryOptions> configureOptions)
{
services.PostConfigure(configureOptions);
// Register lib services here...
// services.AddScoped<ILibraryService, DefaultLibraryService>();
return services;
}
}
Yukarıdaki kodda, :AddMyLibraryService
- IServiceCollection örneğini genişletir
-
Action<T> parametresini
configureOptions,T'ninLibraryOptionsolduğu yer tanımlar -
PostConfigure belirtilen
configureOptionseylemini çağırır
Bu düzendeki tüketiciler, post olmayan bir yapılandırma senaryosunda olduğu gibi bir lambda ifadesi (veya parametreyi Action<LibraryOptions> karşılayan Action<TOptions> bir temsilci) sağlar:
using ExampleLibrary.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddMyLibraryService(options =>
{
// Specify option values
// options.SomePropertyValue = ...
});
using IHost host = builder.Build();
// Application code should start here.
await host.RunAsync();