【问题标题】:Good practic, where the logic must to be? MVC (business layer)好的做法,逻辑必须在哪里? MVC(业务层)
【发布时间】:2015-07-04 03:12:29
【问题描述】:

我正在使用 MVC 如您所见,我从这个开始..

我已经构建了一个简单的销售模块

下一个代码用于返回详细信息的部分视图。

我不确定是否所有这些代码都必须在控制器上。 那我该把“逻辑”放在哪里呢?

我相信我需要它的“业务层”,但对于 mvc。

[HttpPost]
public ActionResult getdetail(int productoid, int ventaid, float cantidad, string codigobarras)
{
codigobarras =((string.IsNullOrEmpty(codigobarras))?"":codigobarras.ToLower());
Models.Helper.Ventah vh = new Models.Helper.Ventah();
vh.listadoclientes = db.accounts.ToList();
vh.listadoproductos = db.products.ToList();
vh.venta = db.sales.Where(x => x.id == ventaid).FirstOrDefault();
if (productoid == 0)
{ 
//si es 0 lo busco por el código de barras
vh.productoseleccionado = vh.listadoproductos.Where(x => x.code.ToLower().Equals(codigobarras)).FirstOrDefault();
}
else {
//busco el producto por el id
vh.productoseleccionado = vh.listadoproductos.Where(x => x.id == productoid).FirstOrDefault();
}

//regreso el partialview si el objecto es null, de lo contrario continuo
//gracias a esto podre mandar un mensaje "producto no encontrado"
if (vh.productoseleccionado == null)
{
vh.mensaje = "No se encontró ningun producto con el código "+codigobarras;
return PartialView(vh);
}
productoid = vh.productoseleccionado.id;
//veo si ya tiene el producto agregado
var detalle=vh.venta.saledetails.Where(x => x.idproduct == productoid).FirstOrDefault();

if (detalle != null)//significa que ya tiene el producto agregado por lo tanto solo lo sumo
{
//valido que, quepa la cantidad que se ingresó
if (vh.productoseleccionado.amount >= cantidad)
{
vh.productoseleccionado.amount = vh.productoseleccionado.amount - cantidad;
detalle.amount += cantidad;
}
}
else//significa que no tiene el producto aún por lo tanto debo agregarlo
{
//valido que, quepa la cantidaqd que se ingresó
if (vh.productoseleccionado.amount >= cantidad)
{
//agrego el detalle
vh.venta.saledetails.Add(
//creo el detalle
detalle = new Models.saledetail()
{
amount = cantidad,
idproduct = vh.productoseleccionado.id,
idsale = vh.venta.id,
inputprice = vh.productoseleccionado.inputprice,
outputprice = vh.productoseleccionado.outputprice,
ivaprice = vh.productoseleccionado.ivaprice,
});
}
}
db.SaveChanges();
return PartialView(vh);
}

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-4


    【解决方案1】:

    我听说过瘦控制器胖模型和胖控制器瘦模型。它更可能取决于您如何使用模型和控制器。例如,假设您有一个音乐应用程序,模型是一首歌曲和一个用户。购买操作(在控制器中)让用户购买歌曲会更有意义......有点像User.Purchase(Song)。而影响整个系统的东西,比如服务器共享音乐的开/关开关,可能会将逻辑放置在控制器中,并检查模型用户是否有权限。

    这个问题有点过于个人/企业的选择,每个人都有自己的喜好,但通常只要在代码中有意义就可以了。除了视图中的逻辑......避免视图中的逻辑。

    【讨论】:

      【解决方案2】:

      您可以考虑使用与 MVC 一起工作的服务存储库(或只是存储库)模式。这里的概念是控制器用一个存储库对象(一个专门用于与数据库交互的层)实例化一个服务对象(一个用于在数据上运行逻辑的层)。这样做的最大好处是逻辑抽象,特别是从单元可测试性的角度来看。 Controller 现在只负责委派传入的数据和准备响应,Service 处理业务逻辑(可测试代码的首当其冲的地方),Repository 只担心数据访问。下面是一个如何布局的示例,虽然在逻辑复杂性上有所简化:

      控制器

      public ActionResult GetDetail(int Id)
      {
          // Do any manipulating of the data sent to the controller
      
          // Instantiate a service for working with Products
          var service = new ProductService(new ProductRepository("connectionString"));
      
          // The method off the Service intended for this controller action
          var modelForPartialView = service.GetProductDetail(Id);
      
          // Return your updated model
          return PartialView(modelForPartialView);
      }
      

      服务

      private ProductRepository _productRepository;
      
      public ProductService(ProductRepository repo)
      {
          _productRepository = repo;
      }
      
      public Product GetProductDetail (int Id)
      {
          Product product = _productRepository.GetProductDetail(Id);
      
          // Perform any business logic/manipulation on the Product before returning to the Controller
      
          return product;
      }
      

      存储库

          public ProductRepository(string connectionString)
          {
              // Connection instantiation
          }
      
          public Product GetProductDetail(int Id)
          {
              // Perform data access here
              var data = DoDataAccess();
      
              // Potentially fill a data object as well
              return FillProductWithData(data);
          }
      

      归根结底,利益分离是关键。您觉得自己需要走多远才能达到这种分离程度取决于您自己。

      【讨论】:

        【解决方案3】:

        控制器应该只包含应用程序逻辑,而不是业务逻辑。业务逻辑应该封装在你的领域模型中,但不能分散到控制器中,这会导致代码重复和高昂的维护开销。可以添加一个服务层来提供一系列单独的领域模型无法完成的功能。持久层,即存储库应该处理域模型的映射和持久性。

        //controller
        public class ProductController : Controller{
           private CustomerService _customerService;
        
           public ProductController(CustomerService customerService){
             _customerService = customerService;
           }
        
           [HttpPost]
           public ActionResult Purchase(Product product){
             Boolean success = _customerService.Purchase(product);
        
             return success ? RedirectToAction("Success") : RedirectToAction("Failure"); 
        
           }
        }
        

        控制器只管理应用逻辑,即根据交易结果将客户重定向到相应的页面。

        //service
        public class AppCustomerService : CustomerService{
          private Customer _currentCustomer;
          private UnitOfWork _unitOfWork;
        
          public AppCustomerService(UnitOfWork unitOfWork){
             _unitOfWork = unitOfWork;
             _currentCustomer = _unitOfWork.CustomerRepository.Get(
              CustomerSession.Current.Id);
          }
        
          public Boolean Purchase(Product product){
             if(_currentCustomer.Purchase(product)){
               _unitOfWork.CustomerRepository.Update(_currentCustomer);
               _unitOfWork.Save();
               return true;
             }
        
             return false;
          }
        }
        

        服务类聚合所需的设施,即 CustomerSession、Customer 和 UnitOfWork,以执行购买交易。

        //domain model
        public class Customer{
        
          private long _id;
          private Money _accountBalance;
          private List<Product> _products;
        
          //list of property methods...
        
          public Boolean Purchase(Product product){
        
           //example of business logic
        
           if(_accountBalance < product.Price || product.Quantity == 0){
             return false;
           }
        
           _products.Add(product);
           return true;      
        
          }
        
        }
        

        需求中指定的购买产品的业务逻辑应该在领域模型中实现。

        【讨论】:

          猜你喜欢
          • 2011-12-26
          • 2011-06-01
          • 2013-04-01
          • 2011-05-30
          • 2013-09-04
          • 2014-10-10
          • 1970-01-01
          • 2013-03-04
          • 1970-01-01
          相关资源
          最近更新 更多