谁应该负责获取MVC中的数据?

时间:2011-03-28 18:41:09

标签: asp.net-mvc-3

使用新项目学习ASP.NET MVC,并且不确定某些事情应该发生在哪里。我已经读到ViewModels是一件好事(tm)并且计划以类似的方式进行,但我仍然不完全清楚模型与控制器的责任。

ViewModel应该负责从ORM实际加载自己吗?因此,控制器只调用ViewModel.GetObject()并将结果传递回视图?

或者我应该在Controller中加载数据,然后将其转换为ViewModel?这似乎在Controller中投入了大量的工作,但应该保持一定的轻量级。

我想我也可能有第三方负责提取数据,然后Controller会调用它并将其转换为适当的ViewModel。

所以对什么是“最佳”方法的想法?

2 个答案:

答案 0 :(得分:5)

控制器将创建viewmodel对象并使用模型填充它。该模型应使用ORM来获取数据。

ViewModel始终仅针对视图,并且该模型特定于域。在CQRS中,您实际上只需获取ViewModel并将其发送到视图。

从控制器中,您可以执行使视图发生CRUD所需的一切。如果您使用Repo模式,那么如果您使用NHibernate或EF直接使用酷炫的工具。一旦ViewModel进入视图,它将与数据库之类的所有内容断开连接,因此在它到达之前将其填满。

答案 1 :(得分:1)

我个人使用存储库。因此,控制器查询存储库并获取模型,然后将模型映射到视图模型并将视图模型传递给视图。例如:

public class ProductsController: Controller
{
    private readonly IProductsRepository _repository;
    private readonly IMapperEngine _mapper;
    public ProductsController(IProductsRepository repository, IMapperEngine mapper)
    {
        _repository = repository;
        _mapper = mapper;
    }

    public ActionResult Index(int id)
    {
        Product product = _repository.GetProduct(id);    
        ProductViewModel viewModel = _mapper.Map<Product, ProductViewModel>(product);
        return View(viewModel);
    }
}

因为这是重复的逻辑,我使用自定义动作过滤器:

public class ProductsController: Controller
{
    private readonly IProductsRepository _repository;
    public ProductsController(IProductsRepository repository)
    {
        _repository = repository;
    }

    [AutoMap(typeof(Product), typeof(ProductViewModel))]
    public ActionResult Index(int id)
    {
        Product product = _repository.GetProduct(id);    
        return View(product);
    }
}

在这种情况下,自定义操作过滤器会拦截操作的结果,并使用相应的映射层替换它。

实现此存储库的方式不是控制器的责任(无论是ORM,直接SQL查询,还是远程Web服务调用)。只要注入一些适当的实现,它就可以工作,这样可以在应用程序的不同部分之间实现较弱的耦合,并且可以单独进行单元测试。所以在这个例子中,它是负责获取数据的存储库的实现。