DDD:测试实体存在的逻辑应该去哪里?

use*_*300 6 domain-driven-design ddd-repositories ddd-service

我正在重构应用程序,并试图找出某些逻辑应该适合的位置。例如,在注册过程中,我必须根据用户的电子邮件地址检查用户是否存在。由于这需要测试用户是否存在于数据库中,因此该逻辑似乎不应该与模型绑定,因为它的存在是由它在数据库中决定的。

但是,我将在存储库上有一个方法,负责通过电子邮件等方式获取用户。这将处理有关检索用户(如果存在)的部分。从用例的角度来看,注册似乎是一个用例场景,因此似乎应该有一个带有注册方法的 UserService(应用程序服务),该方法将调用存储库方法并执行 if then 逻辑以确定返回的用户实体是否为空与否。

就 DDD 而言,我是否在正确的轨道上使用这种方法?我是否以错误的方式看待这个场景,如果是这样,我应该如何修改我的想法?

此链接是作为一个可能的解决方案提供的,在何处检查用户电子邮件尚未退出?. 它确实有帮助,但似乎并没有结束这个问题的循环。我在本文中似乎遗漏了谁将负责调用 CreateUserService、应用程序服务或聚合根上的方法,其中 CreateUserService 对象将与任何其他相关参数一起注入到方法中?

如果答案是应用程序服务,您似乎通过将域服务从域层中取出而失去了一些封装。另一方面,走另一条路意味着必须将存储库注入域服务。这两个选项中哪一个更可取,更符合 DDD?

jlv*_*ero 4

我认为最适合这种行为的是领域服务。DS 可以访问持久性,以便您可以检查是否存在或唯一性。查看此博客条目以获取更多信息。

IE:

public class TransferManager
    {
        private readonly IEventStore _store;
        private readonly IDomainServices _svc;
        private readonly IDomainQueries _query;
        private readonly ICommandResultMediator _result;

        public TransferManager(IEventStore store, IDomainServices svc,IDomainQueries query,ICommandResultMediator result)
        {
            _store = store;
            _svc = svc;
            _query = query;
            _result = result;
        }

        public void Execute(TransferMoney cmd)
        {
            //interacting with the Infrastructure
            var accFrom = _query.GetAccountNumber(cmd.AccountFrom);

            //Setup value objects
            var debit=new Debit(cmd.Amount,accFrom);

            //invoking Domain Services
            var balance = _svc.CalculateAccountBalance(accFrom);
            if (!_svc.CanAccountBeDebitted(balance, debit))
            {
                //return some error message using a mediator
                //this approach works well inside monoliths where everything happens in the same process 
                _result.AddResult(cmd.Id, new CommandResult());
                return;
            }

            //using the Aggregate and getting the business state change expressed as an event
            var evnt = Transfer.Create(/* args */);

            //storing the event
            _store.Append(evnt);

            //publish event if you want
        }
    }
Run Code Online (Sandbox Code Playgroud)

来自http://blog.sapiensworks.com/post/2016/08/19/DDD-Application-Services-Explained