一种策略是实施可以验证约束的服务。
public interface IWebsiteUniquenessValidator
{
bool IsWebsiteUnique(string websiteUrl);
}
这样您就可以实现它,你怎么做,这将取决于多种因素,我不知道,但我建议不要担心通过域去。简单一点,它只是一个查询(* - 我会在底部添加)。
public class WebsiteUniquenessValidator : IWebsiteUniquenessValidator
{
//.....
}
然后,“注入”到需要它的方法中。我说“注入”是因为我们将它从域外提供给域对象,但是..我们将使用方法参数而不是构造函数参数来实现(为了避免要求我们的实体被我们的IoC容器实例化)。
public class User
{
public void AddWebsite(string websiteUrl, IWebsiteUniquenessValidator uniquenessValidator)
{
if (!uniquenessValidator.IsWebsiteUnique(websiteUrl) {
throw new ValidationException(...);
}
//....
}
}
无论你的用户和信息库的消费者 - 如果这是一个服务类或CommandHandler - 可以提供独特的验证依赖。该消费者应该已经通过国际奥委会有线了,因为它会消耗UserRepository:
public class UserService
{
private readonly IUserRepository _repo;
private readonly IWebsiteUniquenessValidator _validator;
public UserService(IUserRepository repo, IWebsiteUniquenessValidator validator)
{
_repo = repo;
_validator = validator;
}
public Result AddWebsiteToUser(Guid userId, string websiteUrl)
{
try {
var user = _repo.Get(userId);
user.AddWebsite(websiteUrl, _validator);
}
catch (AggregateNotFoundException ex) {
//....
}
catch (ValidationException ex) {
//....
}
}
}
*我提到做验证简单,避免域。
我们构建域来封装与修改数据有关的常常复杂的行为。
什么经验表明,关于数据变化的要求与查询数据的要求有很大不同。
这似乎是你遇到的一个痛点,因为你试图强制读取通过写入系统。
为了减轻这些痛点,可以从写入端分离数据从域中读取数据。
CQRS是该技术的名称。我只是说,一旦我在CQRS的上下文中查看DDD,就会点击一大堆灯泡。我强烈建议试着理解CQRS的概念。
是的,但是当一个网站无法在没有用户的情况下存在(一对多)时,我将如何搜索与具有特定URL的网站相关联的用户? – ebb 2011-02-10 22:24:47
@ebb,最终,我只是提出了一些简单的选择:从用户u选择u.UserId加入w.UserId = u.UserId的网站w其中w.Url = @ url`(但由您的存储库的成语指定标准)。 – 2011-02-11 01:54:36