And*_*ita 4 domain-driven-design
如果我错了,请纠正我(并添加您认为正确的其他内容):
应用服务...
域服务...
您对应用程序服务的定义是正确的。我将应用程序服务更多地视为命令处理程序。接收命令,加载聚合,调用聚合方法并保存机会。一个命令在单个事务中处理。
领域服务用于执行聚合需要但无法执行的操作。典型的例子可以是从外界检索附加信息或进行一些计算。应用服务不一定知道聚合是否需要这个或那个信息,但它可以解决必要的依赖关系,并在调用聚合时将域服务传递给聚合。
在我的实践中,领域服务通常作为函数来实现。请记住,域服务并非专门由聚合使用。复杂的值对象可以完美地使用领域服务来达到相同的目的。
在我的书中,我使用域服务来允许值对象确保它不会使用包含脏话的文本进行实例化。
public static DisplayName FromString(
string displayName,
CheckTextForProfanity hasProfanity)
{
if (displayName.IsEmpty())
throw new ArgumentNullException(nameof(FullName));
if (hasProfanity(displayName).GetAwaiter().GetResult())
throw new DomainExceptions.ProfanityFound(displayName);
return new DisplayName(displayName);
}
Run Code Online (Sandbox Code Playgroud)
因此,域服务契约(在这种情况下是一个命名委托)是在域中定义的,
namespace Marketplace.Domain.Shared
{
public delegate Task<bool> CheckTextForProfanity(string text);
}
Run Code Online (Sandbox Code Playgroud)
但它的实现是基础设施问题,并且正在应用程序端进行连接。
namespace Marketplace.Infrastructure
{
/// <summary>
/// PurgoMalum is a simple, free, RESTful web service for filtering and removing content of profanity, obscenity and other unwanted text.
/// Check http://www.purgomalum.com
/// </summary>
public class PurgomalumClient
{
private readonly HttpClient _httpClient;
public PurgomalumClient() : this(new HttpClient()) { }
public PurgomalumClient(HttpClient httpClient) => _httpClient = httpClient;
public async Task<bool> CheckForProfanity(string text)
{
var result = await _httpClient.GetAsync(
QueryHelpers.AddQueryString("https://www.purgomalum.com/service/containsprofanity", "text", text));
var value = await result.Content.ReadAsStringAsync();
return bool.Parse(value);
}
}
}
Run Code Online (Sandbox Code Playgroud)