在我的MVC应用程序中,我有这个流程:
Views <- Controller -> Service layer -> Repository layer -> EF
我对Controller和Service层之间的最佳实践有一些疑问。我的控制器位于Project.Web
中的Project.Domain
服务层。
我想从我的数据库中获取10个热门产品的列表,因此在我的ProductService
我有方法GetPopularProducts
,我使用我的CrudService GetAll
方法。
我的第一个问题。获得实体所需部分的最佳做法是什么?在ProductService
我操作完整实体或CrudService
我应该从ProductService获取有关选择字段和Take(10)的信息吗?
接下来,List将返回Controller。我有ProductDetailViewModel
。我应该将Product
实体映射到ProductDetailViewModel
的哪个位置?在Controller或我的ProductService
?
我问,因为我不想通过我的每一层传递100个字段的Product实体(我只需要10个字段)。我怎么能这样做?从哪里CRUDService应该获取我需要哪些字段的信息?来自ProductService?
我的ProductDetailViewModel需要保存在Project.Web
中的10个字段,因为我的View正在使用它,因此我只能在从我的服务返回List后才能映射我的实体。这是个好主意?
答案 0 :(得分:1)
这取决于您的要求。
一种选择是为小型(非业务逻辑)操作创建存储库。例如GetTopProducts(int count)并在您的服务中使用存储库。
最好不要直接使用存储库(更好地用于单元测试,或者如果您计划将来更改ORM)。而是使用接口和依赖注入(来自您的MVC应用程序)。
示例:
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();
}
}
注意:有许多IoC容器用于依赖注入。例如Ninject
答案 1 :(得分:0)
你应该更好地创建一个方法,直接要求从控制器到EF的第10个。然后在EF,你只需选择第10个问题!
GetPopularProducts必须只返回10个项目,而不是全部!换句话说,当您要求提供10种产品时,必须从数据库中返回10种产品。我可以建议你使GetPopularProduct(int numberOfProducts)方法变得更灵活: - )