Mad*_*Max 3 c# domain-driven-design dependency-injection
我正在学习域驱动设计,并且对实体和向其注入域服务有些困惑。我发现此博客的结论是将服务注入实体是一个坏主意。我部分同意这一点,但是在这种情况下该怎么做:我有一个User实体,它是一个聚合根,其中包含Password值对象。看起来像这样:
密码值对象:
public class Password
{
public string Hash { get; private set; }
public string Salt { get; private set; }
private readonly IHashGeneratorService _hashGeneratorService;
public Password(IHashGeneratorService hashGeneratorService)
{
_hashGeneratorService = hashGeneratorService;
}
public void GenerateHash(string inputString)
{
//Some logic
Salt = hashGeneratorService.GenerateSalt();
Hash = hashGeneratorService.GenerateHash(inputString);
}
}
Run Code Online (Sandbox Code Playgroud)
用户实体:
public class User
{
public Password Password { get; private set; }
public User(IHashGeneratorService hashGeneratorService)
{
this.Password = new Password(hashGeneratorService);
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,如果我通过工厂创建User实体,则需要向工厂构造函数或Create()方法提供IHashGeneratorService实现。在那之后,如果我的工厂被使用,例如。SomeUserService我必须为其提供实现(例如,通过ctor注入)。依此类推...老实说,它从我身上散发出来,因为我的许多类都依赖于哈希生成器服务实现,但只有密码类使用它。而且我认为这也违反了密码类的SRP原理。
我发现了一些解决方案:
使用服务定位器。但是它也有气味,因为它是一种反模式,如果我们使用它很难测试和管理实体。
直接在密码方法中实现哈希算法。
坚持上面所说的:)缺点,优点是我的类更易于测试,因为我可以提供模拟服务而不是完整实现。
就我个人而言,我倾向于将我的代码重新构造为第二种解决方案,因为它不会破坏SRP(或者会破坏SRP?:)),类不依赖于哈希服务实现。还有吗?还是您还有其他解决方案?
我对DDD相当陌生,但是我相信散列密码不是域的问题,而是技术上的问题,就像持久性一样。哈希服务应在domain中定义其接口,但应在基础结构层中实现。然后,应用程序服务将使用哈希服务对密码进行哈希处理并创建Password实例(应该是值对象),然后再将其传递给User聚合根。
在某些情况下,例如依赖项解析非常复杂且特定于域时,聚合必须使用服务。在这种情况下,应用程序服务可以将域服务传递到聚合方法中。然后,聚合将向该服务进行两次分派以解析引用。
有关更多信息,您可以阅读Vaughn Vernon编写的《实现域驱动的设计》一书。他在第362页(模型导航)中谈到了这一点,在本书的其他一些地方也谈到了这一点。
| 归档时间: |
|
| 查看次数: |
1519 次 |
| 最近记录: |