Domain driven design 我应该始终使用服务,还是可以直接使用存储库?

Domain driven design 我应该始终使用服务,还是可以直接使用存储库?,domain-driven-design,Domain Driven Design,当我尝试遵循DDD时,是否应该始终通过服务 或者我可以直接使用存储库来获取域对象吗?就我个人而言,我不喜欢在控制器或表示层中看到存储库。但是我已经看过很多次了,在DDD的背景下,它没有什么问题 我认为答案是,这取决于你的项目有多大。服务层通常出现在更复杂的项目中。而简单的MVC网站只是直接使用存储库 或者我可以直接使用存储库来获取域对象吗 你当然可以。这正是存储库的目标。我想知道如果不是这样,您会使用哪种服务(SOA或基于web服务的体系结构的特定上下文除外)。在完成我的第一个使用DDD原则构建

当我尝试遵循DDD时,是否应该始终通过服务


或者我可以直接使用存储库来获取域对象吗?

就我个人而言,我不喜欢在控制器或表示层中看到存储库。但是我已经看过很多次了,在DDD的背景下,它没有什么问题

我认为答案是,这取决于你的项目有多大。服务层通常出现在更复杂的项目中。而简单的MVC网站只是直接使用存储库

或者我可以直接使用存储库来获取域对象吗


你当然可以。这正是存储库的目标。我想知道如果不是这样,您会使用哪种服务(SOA或基于web服务的体系结构的特定上下文除外)。

在完成我的第一个使用DDD原则构建的项目后:,我发现,让应用层可以使用域服务和存储库是很有用的

关键点:应用层可能是您的WCF服务或web服务中的代码(如果您正在使用该体系结构)。这完全取决于您的实现。如果它适合您的实现,那么您的应用程序层可能与您的表示层相同,从而使应用程序层代码位于控制器中或web表单代码后面

存储库的功能类似于内存中的集合。对于应用层来说,代码应该看起来像是在使用任何旧的集合

域服务的功能更像信息的处理器或访问器,这些信息永远不会被更新,可能会被处理,但不会直接更新。对于应用层来说,代码应该看起来像是在使用任何旧的web服务

话虽如此,我会以一些例子作进一步解释:

存储库

我的存储库实际上继承自一个通用集合,该集合由我创建的一个实现对象键入,该实现对象将数据库键和业务模型封装在一起。使用这种方法,我可以在接口中定义一个索引器,例如

BusinessObject this[int index];
我可以有一个getter,它将根据基础集合的索引返回业务对象,还有一个setter,它将从基础集合中查找数据键并将对象保存到数据库。例如,这使得应用程序代码非常简单

IBusinessObjectRepository repository = new SqlBusinessObjectRepository(sqlString);
BusinessObject obj = repository[0]; //Get first object in the list.
//Make some changes to the business object by setting properties or calling methods to process business logic.
repository[0] = obj; //Save the object back to the database.
服务

我使用服务来检索实体和值对象的列表,我不打算单独编辑这些实体和值对象,在我的情况下,在调用聚合根上的方法时,这些实体和值对象仅用作可用的选择或值。通常,我将这些信息缓存在web服务器上。这不是域服务的唯一用途,只是我的示例。应用层代码仍然相对简单

IBusinessService service = new ImplBusinessService(implementationArgs);
List<BusinessObject> objsToCache = service.GetBusinessObjects();
//cache the objects on the web server.
IBusinessService=new ImplementBusinessService(implementationArgs);
List objsToCache=service.GetBusinessObjects();
//在web服务器上缓存对象。

总之,根据我对DDD原则的理解,应用程序层应该能够从服务或存储库访问业务对象。它们之间的选择取决于什么最适合域模型

“我不喜欢在控制器中看到存储库”=>您能详细说明一下为什么以及在控制器和存储库之间添加什么中间层吗?控制器往往会很快膨胀。其中一个原因是,开发人员最终会将业务逻辑卡在控制器中。业务逻辑应该首先存在于域层,然后存在于服务层——不在控制器中,也不在存储库中。通过在控制器中使用(应用程序)服务,可以避免这种情况。例如,您可以调用accountService.GetUserByEmail(电子邮件)或Catalogeservice.GetProductViewModel。您的控制器保持良好和精益,您的应用程序服务协调与各种存储库的对话。仅仅因为您从存储库中获得了一个对象并不意味着您需要处理业务逻辑。它只是让对象从域层穿过,在另一层中使用。我看不出单行userRepository.GetUserByEmail(电子邮件)比accountService.GetUserByEmail(电子邮件)更能膨胀控制器。如果您告诉我您的服务将域对象转换为ViewModel对象,那么它可能很有用,但这通常也可以在控制器中完成,而且它也不能证明“您不应该在控制器中使用存储库”这样一个明确的断言是正确的。除此之外,我看不到这样一个间接层的好处。你把我的“我不喜欢看…”变成了“你不应该用…”。前者意味着偏好。我不是想告诉你该怎么做。你的问题总是会给出一个主观的答案,这里没有对错之分。我的意思是,作为一个处理过大型控制器的人,我更喜欢并建议尽可能多地将代码保留在控制器之外。我还使用规范模式将查询保留在域层中。有关更多信息,请参阅。我(预期)的问题是,我是否可以绕过服务,直接从存储库(例如,在MVC控制器中)获取域实体嗯,我说对了,答案是肯定的:)有趣的是,如果你看看原始的DDD书籍,你会发现一些被认为是完全正常和普通的东西,现在的运动似乎吓坏了人们……我并不害怕。我只是想知道最好的做法是什么。这本书是九年前出版的,从那时起可能发生了一两件事……没有最佳实践,只有适合特定环境的实践。现在你写的两行没有给我们太多的上下文。。。