| کانال توسعه‌دهندگان سی‌شارپ |
1.03K subscribers
19 photos
3 videos
21 links
⭕️ کانال توسعه‌دهندگان سی‌شارپ دولوپیکس

💠 دولوپیکس | جامعه توسعه‌دهندگان ایرانی

💎 @Developix
🚀 Developix.ir

📌 پشتیبانی و تبلیغات:
@DevelopixSupport
Download Telegram
‏Dependency Injection تمیز در ASP.NET Core برای تست‌پذیری بهتر ⚙️

یکی از مهم‌ترین قدم‌ها برای Clean Code در پروژه‌های ASP.NET Core این است که وابستگی‌ها را مستقیم new نکنیم، بلکه از Dependency Injection استفاده کنیم. این کار هم کد را تمیزتر می‌کند، هم تست‌پذیری و امکان تغییر پیاده‌سازی‌ها را بالا می‌برد. 💡

فرض کنید در یک Web API کنترلری دارید که مستقیم وابسته به Service است:

public class OrdersController : ControllerBase
{
private readonly OrderService _orderService;

public OrdersController()
{
_orderService = new OrderService();
}

[HttpGet("api/orders/{id}")]
public async Task<IActionResult> Get(int id)
{
var order = await _orderService.GetByIdAsync(id);
return order is null ? NotFound() : Ok(order);
}
}


این طراحی چند مشکل جدی دارد:

• کنترلر مستقیماً به OrderService Couple شده است.
• تست Unit برای کنترلر سخت است، چون نمی‌توان Mock تزریق کرد.
• در آینده اگر سرویس عوض شود (مثلاً کش اضافه شود)، باید خود کنترلر را تغییر بدهید.

راه تمیزتر این است که یک Interface تعریف کنید و آن را از DI Container تزریق کنید:

public interface IOrderService
{
Task<Order?> GetByIdAsync(int id);
}

public class OrderService : IOrderService
{
private readonly AppDbContext _db;

public OrderService(AppDbContext db)
{
_db = db;
}

public Task<Order?> GetByIdAsync(int id)
=> _db.Orders.FindAsync(id).AsTask();
}


حالا کنترلر فقط Interface را می‌شناسد:

[ApiController]
[Route("api/[controller]")]
public class OrdersController : ControllerBase
{
private readonly IOrderService _orderService;

public OrdersController(IOrderService orderService)
{
_orderService = orderService;
}

[HttpGet("{id}")]
public async Task<IActionResult> Get(int id)
{
var order = await _orderService.GetByIdAsync(id);
return order is null ? NotFound() : Ok(order);
}
}


و در Program.cs (یا Startup قدیمی‌ها):

builder.Services.AddScoped<IOrderService, OrderService>();


مزیت‌ها 🧩

• تست‌پذیری بالا: در تست‌ها می‌توان یک FakeOrderService یا Mock تزریق کرد.
• پیاده‌سازی قابل‌تعویض: بدون تغییر کنترلر می‌توانید CachingOrderService اضافه کنید.
• رعایت اصل D از SOLID (Dependency Inversion): وابستگی به Abstraction نه Concrete Class.

برای مطالعه بیشتر، مستندات رسمی مایکروسافت درباره DI در ASP.NET Core خیلی شفاف و به‌روز است:
Microsoft Learn - Dependency injection in ASP.NET Core

قدم‌به‌قدم اگر وابستگی‌های مستقیم را به شکل Interface + DI تبدیل کنید، معماری اپلیکیشن تمیزتر، منعطف‌تر و آماده‌ٔ رشد می‌شود. 🚀

🔖 #CSharp #سی_شارپ #C# #_NET #ASP_NET_Core #Dependency_Injection #SOLID #Clean_Code

👤 Developix

💎 Channel: @DevelopixCSharp
👍31