Reputation: 207
In my MVC application I have this flow:
Views <- Controller -> Service layer -> Repository layer -> EF
I have some questions about what is the best practise to have between Controller and Service layer. My Controller is in the Project.Web
, Service Layer in the Project.Domain
.
I want to get list of 10 popular products from my database, so in my ProductService
I have method GetPopularProducts
where I use my CrudService GetAll
method.
There is my first question. What is the best practise to get only needed part of entity? In ProductService
where I operate on full entity or in CrudService
where I should have information from ProductService about select fields and Take(10) ?
Next, List is returning to the Controller. I have ProductDetailViewModel
. Where should I map Product
entity to ProductDetailViewModel
? In the Controller or in my ProductService
?
I ask because I dont want to pass my Product entity with 100 fields through my every layer (I need only 10 fields). How I can do that? From where CRUDService should get the information which fields I need? From ProductService?
My ProductDetailViewModel with needed 10 fields I keep in Project.Web
, because my View is using it, so I can map my entity only after returning List from my Service. This is good idea?
Upvotes: 0
Views: 499
Reputation: 5899
It depends on your requirements.
One option is to create repositories for small (not business logic) operations. Such as GetTopProducts(int count) and use repositories in your service.
It will be better to not use repositories directly (better for unit tests or if you plan in future to change ORM). Instead use interfaces and dependency injection (from your MVC app).
Example:
public interface IProductRepository
{
Product GetTopProducts(int count);
}
public class ProductRepository : IProductRepository
{
public Product GetTopProducts(int count)
{
// EF select goes here
}
}
public class ProductService
{
private IProductRepository productRepository;
public ProductService(IProductRepository productRepository)
{
this.productRepository = productRepository;
}
public Product GetTopProducts()
{
// Business logic goes here...
productRepository.GetTopProducts(10);
// Business logic goes here...
}
}
public class ProductController : Controller
{
private ProductService productService;
public ProductController(ProductService productService)
{
this.productService = productService;
}
public ActionResult Products()
{
productService.GetTopProducts();
return View();
}
}
Note: There are many IoC containers for dependency injections. for example Ninject
Upvotes: 1
Reputation: 4266
You should better create a method that directly asks for the 10th from the controller to the EF. Then in EF, you just select the 10th asked!
GetPopularProducts must return only 10 items, not all! In other words, when you ask for your 10 product, there mist be 10 products that must be returned from theDB. I can advice you to make kind of GetPopularProduct(int numberOfProducts) method to be more flexible :-)
Upvotes: 0