ASP.Net MVC2中Controller和Repository之间的职责范围

时间:2010-07-16 13:01:33

标签: asp.net-mvc-2

我正在尝试了解如何使用存储库构建ASP.Net MVC2 Web App。

我阅读的很多示例,教程和书籍都是如此构建应用程序:

public interface IProductsRepository
{
    IQueryable<Product> Products { get; }
}

public class SqlProductsRepository : IProductsRepository
{
    public Table<Product> productsTable;

    public IQueryable<Product> Products
    {
        get { return productsTable }
    }
}

public class ProductsController : Controller
{
    IProductsRepository productsRepository;
    public ProductsController(IProductsRepository productsRepository)
    {
       // set the Repository
    }

    public ActionResult GetLatestPublishedProducts(int pageSize, int page, ref int totalItemCount)
    {
        // Do LINQ query 
        return View(from p in productsRepository
                    where p.PublishedOn != null 
                    orderby p.ProductId descending 
                    select to(p))
                    .Skip((page  - 1) * pageSize)
                    .Take(pageSize)
                    .ToList());
    }
}

我不明白的一件事是为什么Linq查询存在于控制器中。

我想知道为什么做这样的事情是不对的:

public class SqlProductsRepository : IProductsRepository
{
    // set data model stuff here

    public List<Product> GetLatestPublishedProducts(int pageSize, int page, ref int totalItemCount) {
        // DO LINQ Query in here
    }
}

public class ProductsController : Controller
{
    // set repository stuff here

    public ActionResult GetLatestPublishedProducts(int pageSize, int page, ref int totalItemCount)
    {       
        return View(productsRepository.GetLatestPublishedProducts(pageSize, page, totalItemCount));
    }
}

3 个答案:

答案 0 :(得分:7)

你的第二个例子就是你应该做的事情。存储库应处理所有数据访问。

控制器应该只获取已经过滤/排序的数据并将其传递给视图。控制器不应该对任何数据或业务逻辑负责。它应该只负责检索数据并传递它。

在控制器中编写代码时,我问自己这个问题;

  

我是否必须再次编写此代码   如果我要写这个应用程序   的WinForms?

因此,您的IProductsRepository将拥有GetLatestPublishedProducts方法,然后您将在SqlProductsRepository中实施该方法。

责任是:

  • 存储库 - 从中​​获取数据 数据库
  • 控制器 - 将数据传递给View 用于渲染

然后,您可以更进一步,将任何业务逻辑分离出来,以便Controller本身避免使用存储库。因此,您将拥有位于Controller和存储库之间的第三个服务层。

答案 1 :(得分:4)

检查不同类别的意图。

  • 存储库:提供对数据库的访问
  • 控制器:控制您网站的流量(我知道,有更好的意图)

这意味着,如果您将Linq视为您的主要业务逻辑,那么它应该不是2中的任何一个。 我会创建一个ProductService,它包含所有这些抽象的调用,因为它们将被重复使用。

服务应该是什么:

from p in productsRepository
                    where p.PublishedOn != null 
                    orderby p.ProductId descending 
                    select to(p))

控制器应该是什么:

from p in productService.GetLatestPublishedProducts()
                    .Skip((page  - 1) * pageSize)
                    .Take(pageSize)

如果可能的话,使用IEnumerable。不是清单。

答案 2 :(得分:1)

实现保持控制器精益的目标。这有助于保持秩序井然有序。使用存储库来处理所有数据访问逻辑。我还包括一个服务层来处理其他业务和验证逻辑。因此,像Create这样的控制器,服务和存储库方法看起来像这样:

// Controller
public ActionResult Create(MyModel myModel)
{
    if (!_service.CreateMyModel(myModel)) 
    {
        return View(myModel);
    }

    return RedirectToAction("Index");
}

// Service
public bool CreateMyModel(MyModel myModel)
{
    // Validation logic
    if (!ValidateMyModel(myModel))  
    {
        return false;
    }

    return _repository.CreateMyModel(myModel);
}

// Repository
public book CreateMyModel(MyModel myModel)
{
    _entities.AddToMyModelsSet(myModel);
    try
    {
        _entities.SaveChages();
        return true;    
    }
    catch
    {
        return false;
    }
}