هنعمل Refactor للـ Product Controller بدل ما هو بيتعامل مباشر مع الـ Generic Repository هنعمل Product Service وجواها هنعمل الـ Logic بتاع الـ Product Controller وجواها هنتعامل مع الـ Unit of work والـ Unit of work هيتعامل مع الـ Generic Repository والـ Generic هيتعامل مع الـ DbContext

فلو روحنا في الـ Controller هنلاقي انه بيعمل حاجات كتير اوي مثلًا في الـ GetAll وكمان هتلاقينا بنستخدم الـ DI بتاع الـ Generic Repository واحنا اصلا شيلناها من الـ Program

فهنروح نعمل بقا الـ Service

Interface

نروح في الـ Core في الـ Services.Contract ونعمل Interface

public interface IProductService
{
	Task<IReadOnlyList<Product>> GetProductsAsync(ProductSpecParams specParams);
	Task<Product?> GetProductAsync(int productId);
	Task<int> GetCountAsync(ProductSpecParams specParams);
	Task<IReadOnlyList<ProductBrand>> GetBrandsAsync();
	Task<IReadOnlyList<ProductCategory>> GetCategoriesAsync();
}

Class

نروح في الـ Service ونعمل كلاس نروح كمان على الـ Controller وناخد الكود من كل Endpoint

public class ProductService : IProductService
{
	private readonly IUnitOfWork _unitOfWork;
 
	public ProductService(IUnitOfWork unitOfWork)
	{
		_unitOfWork = unitOfWork;
	}
 
	public async Task<IReadOnlyList<Product>> GetProductsAsync(ProductSpecParams specParams)
	{
		var spec = new ProductWithBrandAndCategorySpecifications(specParams);
		var products = await _unitOfWork.Repository<Product>().GetAllWithSpecAsync(spec);
		return products;
	}
	public Task<Product?> GetProductAsync(int productId)
	{
		var spec = new ProductWithBrandAndCategorySpecifications(id);
		var product = await _unitOfWork.Repository<Product>().GetByIdWithSpecAsync(spec);
		return product;
	}
	public Task<int> GetCountAsync(ProductSpecParams specParams)
	{
		var countSpec = new ProductsWithFilterationForCountSpecifications(specParams);
		var count = await _unitOfWork.Repository<Product>().GetCountAsync(countSpec);
		return count;
	}
 
	public Task<IReadOnlyList<ProductBrand>> GetBrandsAsync()
		=> await _unitOfWork.Repository<ProductBrand>().GetAllAsync();
	Task<IReadOnlyList<ProductCategory>> GetCategoriesAsync()
		=> await _unitOfWork.Repository<ProductCategory>().GetAllAsync();
}

بعدين نروح للكنترولر ونعمل Inject للـ IProductService

public class ProductsController : BaseApiController
{
	private readonly IMapper _mapper;
	private readonly IProductService _productService;
 
	public ProductsController(IProductService productService, IMapper mapper)
	{
		_mapper = mapper;
		_productService = productService;
	}
}
 
// At main Services : ApplicationServicesExtension
services.AddScoped(typeof(IProductService), typeof(ProductService));

ونبدأ نعدل كل Endpoint اننا نستخدم الـ Services فيها