طريقة أجمل لحقن الأشياء
عندما أقوم بإنشاء أشياء مثل الخدمات أو المستودعات أو السمات أو أي شيء لإدخاله في تطبيقاتي، هناك هذه الخطوة التي يجب علينا القيام بها، وهي إضافة الخدمات فعليًا إلى التطبيق.
هذا هو نفسه دائمًا، تذهب إلى Program.cs، ثم تنتقل إلى جزء ما من الملف لإضافة builder.Services.AddScoped<MyService>(); من أجل إدخال الخدمة.
شيء من هذا القبيل:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
// Repositories
builder.Services.AddScoped<ARepository>(); // 👀
builder.Services.AddScoped<BRepository>(); // 👀
// Services
builder.Services.AddScoped<AService>(); // 👀
builder.Services.AddScoped<BService>(); // 👀
builder.Services.AddScoped<CService>(); // 👀
builder.Services.AddScoped<DService>(); // 👀
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
أعني أنه يعمل، لكني صعب الإرضاء، ولا أحبه حقًا.
لنفترض أن لدينا عمليات حقن تبعية متعددة نريد القيام بها، وهي ليست في الواقع نفس الأشياء، في حالتي قد يكون هذا شيئًا مثل وجود مكتبة تحتوي على جميع المستودعات، ومكتبة أخرى تحتوي على جميع الخدمات، وأخيرًا، مكتبة أخرى تحتوي على السمات.
في هذه الحالة، هل يمكنك تخيل عدد الأسطر التي يتعين علينا إضافتها إلى Program.cs.
لنفترض أن لدينا مكتبة تحتوي على بعض الخدمات، إذا أردنا تضمين جميع خدماتنا، علينا العمل مع IServiceCollection.
لذلك سنقوم بإنشاء static class الذي سيكون له طريقة static تسمى AddServices والتي تُرجع IServiceCollection.
في هذه الحالة سيتم تسميته IServiceCollectionServicesExtensions.
/// <summary>
/// IServiceCollectionServicesExtensions class
/// </summary>
public static class IServiceCollectionServicesExtensions
{
/// <summary>
/// AddCoreServices
/// </summary>
/// <param cref="IServiceCollection" name="services">Parameter for <see cref="IServiceCollection"/></param>
/// <returns>An object of type <see cref="IServiceCollection"/></returns>
public static IServiceCollection AddServices(this IServiceCollection services)
{
services
.AddScoped<AService>()
.AddScoped<BService>()
.AddScoped<CService>()
.AddScoped<DService>();
return services;
}
}
ليس هذا فحسب، لدينا أيضًا مكتبة أخرى تتضمن بعض المستودعات التي تستخدمها هذه الخدمات، لذلك دعونا نفعل الشيء نفسه.
/// <summary>
/// IServiceCollectionServicesExtensions class
/// </summary>
public static class IServiceCollectionServicesExtensions
{
/// <summary>
/// AddCoreServices
/// </summary>
/// <param cref="IServiceCollection" name="services">Parameter for <see cref="IServiceCollection"/></param>
/// <returns>An object of type <see cref="IServiceCollection"/></returns>
public static IServiceCollection AddRepositories(this IServiceCollection services)
{
services
.AddScoped<ARepository>()
.AddScoped<BRepository>();
return services;
}
}
الآن، لدينا مستودعاتنا وطرق تقديم الخدمات التي تم إنشاؤها، ولكن كيف نستخدمها؟
دعنا نعود إلى Program.cs ونضيف ما يلي:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
// Repositories
builder.Services.AddRepositories(); // 👀
// Services
builder.Services.AddServices(); // 👀
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
هذا يبدو أنظف بكثير، أليس كذلك؟ حسنًا، لقد نجحنا في إدخال بعض الخدمات والمستودعات، لكنها الآن تبدو أجمل ولدينا بالفعل ما نقوم بإدخاله في المكتبة الخارجية.