DDD无状态服务和构造函数注入



在域驱动设计文献中,经常说域服务应该是无状态的。

我相信这是因为服务调用应该代表单个工作单元。不应该存在多个服务方法将使用的任何服务状态。

我在服务体系结构中打破了这一规则,这样我就可以构造函数注入服务中所需的所有相关存储库。示例:

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上使用构造函数注入,我需要具有状态(属性),以便服务方法能够访问相关的存储库等。

尽管我希望将单独的服务方法设计为独立的工作单元,但我不一定能阻止这种情况的发生。

如何构建域服务,使其成为无状态的这有必要吗?

编辑:

Eric Evans领域驱动设计:解决软件核心的复杂性:

当域中的重要进程或转换不是实体或VALUE对象的自然责任,添加操作作为声明为SERVICE的独立接口。定义接口,并确保操作名称是UBIQUITUS LANGUAGE的一部分。提供服务无状态

Vaughn Vernon在他的《实现域驱动设计》一书中也推荐了无状态服务。

在我看来,您混淆了拥有属性和拥有状态。

UserService是一种服务。它只有只读(请删除setters)属性,这些属性是无状态服务,例如IUserRepository。这使得UserService本身成为一个无状态服务。

是的,我们甚至可以在上面添加一个更高级别的服务,它将IUserService作为其组件之一。该服务也将是无状态的。

你问为什么?

无国籍状态的目的(或至少是的目的)是允许控制权倒置:我们将对的控制权交给外部。如果其他人正在控制我们获得的实例,那么这些实例最好是无状态的!如果我们得到了另一个类得到的相同实例,并且我们都开始改变它的状态,该怎么办?结果是不确定的。

的确,如果我们的服务根本没有属性(比如UserRepository),这个问题就可以避免。还请注意,当更高级别的服务(如UserService)独占地具有此类服务的只读属性时,同样可以很好地避免,因为没有什么可分配的。我们可以放心,注入的服务将始终正确运行,因为它的层次结构中没有可依赖的状态。

接近目标的一种方法是将IOC容器注入到服务类中,然后重写属性get方法来解析必要类的实例。你的新课程看起来像这样:

public class UserService : IUserService
{
private IUnitOfWork UnitOfWork 
{ 
get{return container.Resolve<IUnitOfWork>()}
}
private IUnityContainer container {get;set;}
public UserService(IUnityContainer container )
{
this.container = container;
}
public User RegisterNewUser(User user)
{
//Domain logic
}
}

您的服务类现在依赖于IOC容器,这不是一件好事,但如果您试图更接近无状态服务,这可以做到。

相关内容

  • 没有找到相关文章

最新更新