【发布时间】:2014-03-29 01:10:59
【问题描述】:
在领域驱动设计文献中,经常说领域服务应该是无状态的。
我相信这是因为服务调用应该代表单个工作单元。不应该有多个服务方法会使用的任何服务状态。
我在我的服务架构中打破了这条规则,以便我可以构造函数注入服务中所需的所有相关存储库。示例:
public class UserService : IUserService
{
public IUnitOfWork UnitOfWork { get; set; }
public IUserRepository UserRepository { get; set; }
public ICustomerRepository CustomerRepository { get; set; }
public UserService(IUnitOfWork unitOfWork, IUserRepository userRepository, ICustomerRepository customerRepository)
{
UnitOfWork = unitOfWork;
UserRepository = userRepository;
CustomerRepository = customerRepository;
}
public User RegisterNewUser(...)
{
// Perform relevant domain logic
}
// ...
}
为了让我在UserService 上使用构造函数注入,我需要拥有状态(属性),以便服务方法可以访问相关的存储库等。
虽然我希望将各个服务方法设计为独立的工作单元,但我不一定能阻止这种情况发生。
我如何构建域服务以使其无状态?这甚至有必要吗?
编辑:
埃里克·埃文斯Domain-driven Design: Tackling Complexity in the Heart of Software:
当域中的重要过程或转换不是 ENTITY 或 VALUE OBJECT 的自然责任,添加操作 将模型作为独立接口声明为服务。定义 根据模型的语言进行接口,并确保 操作名称是 UBIQUITOUS LANGUAGE 的一部分。做服务 无状态。
Vaughn Vernon还在他的书中Implementing Domain Driven Design推荐了无状态服务。
【问题讨论】:
-
如果你想让服务成为无状态的,你应该通过方法参数传入依赖,但这会非常可怕,并且会将这些依赖从实现细节提升到合同的一部分。
-
是的,那不会很有趣。这也意味着我必须在应用层和/或 MVC 控制器中注入相关的存储库。
-
@Steven:检查我的编辑,谢谢。
-
我相信 Evens 的含义与您想象的不同。我认为他将服务的状态与域对象的状态进行了比较。域对象显然会具有状态并在其生命周期内更改其状态。服务不会或不应该改变状态,我认为这就是他所说的“无状态”。我认为让服务完全无状态是不可能的,因为它总是在某种有状态的上下文中运行;例如一个 UnitOfWork,或者一个数据库事务。无论您注入依赖项还是使用服务位置,服务都将始终受此影响。
-
@Steven:感谢您的澄清。
标签: design-patterns dependency-injection domain-driven-design domainservices onion-architecture