或者我根本不明白这一点。
我已经使用Controller启动了我的ASP.NET MVC应用程序 - > ViewModel - >服务 - >存储库模式。
每种类型的对象(客户,产品,类别,发票等)是否需要拥有自己的存储库和服务?如果是这样,你如何将常见物品放在一起?
我的意思是很多时候会在同一页面上显示其中一些内容。所以我没有得到这个我不认为。
所以我想我需要一个ShopController,它有一个ShopViewModel,它可以有类别,子类别,产品等。但对我来说,问题是它似乎没有很好地融合。
也许ASP.NET WebForms适合像我这样的人:)
修改
汇总也包括:
Product,SubCategory,Product,ChildProduct,ProductReview,Product是聚合根?
然后在ViewModels中,您将访问产品以获取其子产品,评论等。
我正在使用实体框架4,那么如何使用存储库/服务模式实现延迟加载?
答案 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 architecture或Who Can Help Me项目。后者确实展示了一个很好的架构恕我直言。
最后不要忘记层的主要问题之一是可插拔性/可测试性,因此我建议您了解一个好的IoC容器(我是Castle.Windsor的粉丝)。再次,S#arp架构是一个很好的发现方式。
答案 2 :(得分:1)
您可以将多种类型的存储库传递给控制器(我假设您使用某种类型的IoC容器和构造函数注入)。然后,您可以决定从所有传递的存储库中组合某种类型的服务对象。