ASP.NET MVC - 我想我错了

时间:2011-02-22 23:27:45

标签: asp.net-mvc-2 service repository-pattern

或者我根本不明白这一点。

我已经使用Controller启动了我的ASP.NET MVC应用程序 - > ViewModel - >服务 - >存储库模式。

每种类型的对象(客户,产品,类别,发票等)是否需要拥有自己的存储库和服务?如果是这样,你如何将常见物品放在一起?

我的意思是很多时候会在同一页面上显示其中一些内容。所以我没有得到这个我不认为。

所以我想我需要一个ShopController,它有一个ShopViewModel,它可以有类别,子类别,产品等。但对我来说,问题是它似乎没有很好地融合。

也许ASP.NET WebForms适合像我这样的人:)

修改

汇总也包括:

Product,SubCategory,Product,ChildProduct,ProductReview,Product是聚合根?

然后在ViewModels中,您将访问产品以获取其子产品,评论等。

我正在使用实体框架4,那么如何使用存储库/服务模式实现延迟加载?

3 个答案:

答案 0 :(得分:6)

  

是否每种类型的对象(客户,   产品,类别,发票等..)   需要拥有自己的存储库

您的域中每个聚合根应该有一个存储库。有关什么是聚合根的更多信息,请参阅此question

在您提供的示例中,我可以看到CustomerReposiotry将处理检索所有相关客户数据(客户订单下订单有客户)。处理检索产品信息的ProductRepository。

  

和服务?如果是这样,你怎么带   共同的项目在一起?

服务层很不错,但只有在添加此图层时有附加值。如果您的服务只是直接进入存储库,则可能不需要它。但是,如果您需要在Product上执行某些业务逻辑,则ProductService可能有意义。

这可能没有意义

public void UpdateProduct(Product product)
{
  _repo.Update(product);
}

但是如果你有逻辑,那么这个层就可以封装你的产品业务规则。

public void UpdateProduct(Product productToUpdate)
{
  //Perform some sort of business on the productToUpdate, raise domain events, ....
  _repo.Update(productToUpdate);
}
  

所以我觉得我需要一个   ShopController,它有一个   ShopViewModel,可能有   类别,子类别,产品,   但对我来说,问题在于   它似乎没有很好地融合。

如果刷新了域,则视图模型最终有意义

public ActionResult Index()
{
  ShopViewModel shopViewModel = new ShopViewModel();
  shopViewModel.Products = _productRepo.GetAll();
  //other stuff on the view model.
  return(shopViewModel);
}

<强>更新

  

当你还需要时会发生什么   提供无法获得的数据   聚合根?例如,说我   有一个创建客户视图并在   那个观点,我也需要提供   用户与公司的集合   选择关联新的   顾客。是集合   公司来自CustomerRepository   或者你还需要一个   CompanyRepository?

如果公司可以独立生活(例如,您编辑,更新,删除公司),我建议公司也是您域名的集合根(客户有公司,公司有客户列表)。但是,如果公司只能通过客户获得,我会将公司视为ValueType / Value Object。如果是这种情况,我会在客户存储库上创建一个方法来检索所有CompanyNames。

_repo.GetAllCompanyNames();

答案 1 :(得分:4)

存储库是不可或缺的,只需与它们一起使用即可。他们隐藏了数据实施。与ORM一起使用时,您几乎可以忘记核心数据库活动(CRUD)。您通常会发现对象和存储库之间存在1:1的映射,但没有什么能阻止存储库返回它喜欢的任何内容。通常,您将根据实例进行操作。为您的查询创建非对象特定的存储库,这些存储库自然不适合现有的存储库。

你会在“服务”部分找到很多相互矛盾的论点 - 有些人喜欢在域名服务之间分配(我称这些业务规则不适合核心域对象)和应用程序服务(域对象上的操作的逻辑分组)。我实际上已经去了一个名为[ProjectName] .Core.Operations的独立项目,它位于我的[ProjectName] .Core解决方案文件夹中。核心+运营=域名。

操作可能会返回View所需的所有信息的DTO,这些信息是通过域上的许多存储库调用和操作构建的。有些人(包括我自己)更喜欢将存储库完全隐藏在Presentation中,而是使用Operations(Services)作为它们的外观。只要对命名感到直觉,不要害怕,重构是健康的。 HomePageOperations类没有任何问题,方法GetEveryThingINeedForTheHomepage返回一个ThingsINeedForTheHomePage类。

保持控制器尽可能轻。他们所做的只是将数据映射到数据的视图和视图,与“服务”对话并处理应用程序流程。

下载并查看S#arp architectureWho Can Help Me项目。后者确实展示了一个很好的架构恕我直言。

最后不要忘记层的主要问题之一是可插拔性/可测试性,因此我建议您了解一个好的IoC容器(我是Castle.Windsor的粉丝)。再次,S#arp架构是一个很好的发现方式。

答案 2 :(得分:1)

您可以将多种类型的存储库传递给控制器​​(我假设您使用某种类型的IoC容器和构造函数注入)。然后,您可以决定从所有传递的存储库中组合某种类型的服务对象。