پیکربندی هوشمند و تحلیل طولعمر وابستگیها (DI Lifetimes) با GitHub Copilot
نویسنده: وحید نصیری
تاریخ: ۱۴۰۵/۰۵/۲۹ ۱۲:۳۷
آدرس: www.dntips.ir
AddScoped یا AddTransient ثبت میکنند. راهکار مهندسی، وادار کردن Copilot به ارزیابی منطق کلاسی و بررسی دلایل انتخاب هر Lifetime قبل از تغییر کد است.Singleton)، یک سرویس با طولعمر کوتاهتر (Scoped) مانند DbContext را درون سازنده خود دریافت کند:Program.cs، از این الگوی تحلیلی استفاده کنید:کلاسها و اینترفیسهای موجود در فایلهای مشخصشده را تحلیل کن و پیشنهادهای ثبت در Dependency Injection را استخراج کن.
الزامات و مراحل تحلیل:
۱. فعلاً کدی را تغییر نده یا اضافه نکن.
۲. پیشنهادها را به سه دسته تفکیک کن:
DbContext) سروکار دارند.۳. برای هر مورد توضیح بده که چرا آن Lifetime خاص انتخاب شده است.
۴. هشدار بده که آیا در میان کلاسها، ریسک بروز Captive Dependency یا استفاده از فیلدهای دارای وضعیت ناامن (Stateful Fields) وجود دارد یا خیر.
Scoped: سرویسهای OrderService و CustomerRepository: به دلیل وابستگی مستقیم به ApplicationDbContext و نیاز به جداسازی تراکنشها به ازای هر درخواست HTTP.Singleton: سرویسهای SystemClock یا MemoryCacheProvider: فاقد وضعیت متغیر بر اساس درخواست، پیادهسازی Thread-safe و هزینه بالای ساخت مجدد.Transient: سرویسهای OrderValidator و TokenGeneratorHelper: سرویسهای سبک و بدون وضعیت که نگهداری آنها در حافظه نیازی نیست.namespace MyApp.Infrastructure.DependencyInjection;
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddInfrastructureServices(
this IServiceCollection services,
IConfiguration configuration)
{
// سرویسهای Singleton بدون وابستگی به درخواست
services.AddSingleton<IDateTimeProvider, SystemDateTimeProvider>();
// لایه دسترسی به داده و سرویسهای مرتبط (Scoped)
services.AddScoped<IOrderRepository, OrderRepository>();
services.AddScoped<IOrderService, OrderService>();
// ابزارهای محاسباتی سبک (Transient)
services.AddTransient<IOrderPricingCalculator, OrderPricingCalculator>();
return services;
}
}Scrutor و الگوهای Conventions سرویسها را به صورت خودکار رجیستر کند:services.Scan(scan => scan
.FromAssemblyOf<OrderService>()
.AddClasses(classes => classes.Where(type => type.Name.EndsWith("Service")))
.AsImplementedInterfaces()
.WithScopedLifetime());ValidateScopes = true را در کانتینر ASP.NET Core فعال کنید تا بروز هرگونه Captive Dependency در لحظه بالا آمدن برنامه کشف شود.services.AddKeyedScoped) استفاده کنید.