首页 > 解决方案 > DDD中服务的对与错

问题描述

如果我错了,请纠正我(并添加您认为正确的其他内容):

申请服务...

域名服务...

标签: 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);
    }

因此,在域中定义了域服务合同(在这种情况下为命名委托),

namespace Marketplace.Domain.Shared
{
    public delegate Task<bool> CheckTextForProfanity(string text);
}

但它的实现是基础架构问题,并且正在应用程序端进行连接。

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);
        }
    }
}

推荐阅读