好的实践,逻辑必须在哪里? MVC(业务层)

时间:2015-07-04 03:12:29

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

我正在使用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);
}

3 个答案:

答案 0 :(得分:0)

我已经听说过瘦身控制器脂肪模型和脂肪控制器瘦身模型。它更可能取决于您如何使用模型和控制器。比如说你有一个音乐应用程序,模型是一个歌曲和一个用户。在购买动作(在控制器中)使用户购买歌曲更有意义......有点像User.Purchase(Song)。虽然影响整个系统的某些东西,例如服务器用于共享音乐的开/关开关,但可能在控制器中放置逻辑,并且模型用户如果有权限则被检查。

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

答案 1 :(得分:0)

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

<强>控制器

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);
    }

归根结底,利益分离是关键。你觉得你需要达到这种程度的分离程度取决于你。

答案 2 :(得分:0)

控制器应仅包含应用程序逻辑,但不包含业务逻辑。业务逻辑应该封装在您的域模型中,但不应分散到控制器中,这将导致代码重复和高维护开销。可以添加服务层以提供仅由域模型无法实现的一系列功能。持久层,即存储库应该处理域模型的映射和持久性。

//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;      

  }

}

购买产品的业务逻辑应在域模型中实现。