Domain driven design 域服务应该如何调用基础设施服务?

Domain driven design 域服务应该如何调用基础设施服务?,domain-driven-design,Domain Driven Design,1) 当域层使用基础结构服务时,其接口在域层中定义,而其实现在基础结构层中定义 我们不应该将IS(如存储库或电子邮件服务)直接注入域实体: 相反,如果域实体的某个方法需要特定的IS,则应用层可以将该IS作为参数传递给该方法: class Foo { ... public int DoSomething(IRepository repo) { var info = repo.Get...; ..

1) 当域层使用基础结构服务时,其接口在域层中定义,而其实现在基础结构层中定义

我们不应该将IS(如存储库或电子邮件服务)直接注入域实体:

相反,如果域实体的某个方法需要特定的IS,则应用层可以将该IS作为参数传递给该方法:

 class Foo
{
           ...
       public int DoSomething(IRepository repo)
       {
            var info = repo.Get...;
              ...
       }
}
a) 我假设也不应该直接注入域服务:

,但应将IS作为参数传递给打算使用它的域服务方法:

class TransferService
{
         public bool Transfer(IRepository repo)
         {
            var info = repo.Get...;
              ...
         } 
} 
b) 我假设,如果域实体的方法需要使用域服务,它不需要通过参数接收它(尽管将域服务作为参数传递有一个明确传递方法依赖关系的好处),而是可以直接调用它,原因是域实体和域服务都是域概念:

class Foo
{
       ...

       public int DoSomething()
       {
            var info = TransferService.Transfer(...);
              ...
       }
}
更新:

(一)

如果需要,可以将IS注入域服务中 功能-ie未传递给方法。这与 这是因为域服务是无状态的,因此它可以 配置一次所需的依赖项,并在需要时使用, 例如,其他实体

a) 所以IS不应该被注入域实体的主要原因是它们的statefulf性质

b) 但我认为不将注入域实体的主要原因是因为它会违反持久性无知规则

c) 如果我们向实体注入IS,实体的状态完整性会导致什么问题

d) 将IS注入域服务不违反PI吗?若否,原因为何

(二)

域服务应该像您一样作为参数传递给实体 将存储库接口作为参数传递。同样的原则 申请

但与存储库不同,域服务是一个域概念,那么“应用相同的原则”是什么意思呢?也就是说,将域服务注入域实体不会违反PI,而注入存储库则会

第二次更新:

(一)

(a)

这是一个原因。另一个是,这会产生不必要的耦合。如果 实体上的单个行为只需要存储库,为什么 一直把它注入实体?此外,现在你必须考虑如何 您将解决这些依赖关系吗?使实体成为依赖项的一部分 注入图?这很快会使管理层的职责负担过重 实体

因此,如果我理解正确-将IS注入域服务DS不会违反SRP,因为DS正在使用它执行其指定任务(即其指定职责),将IS注入域实体违反了SRP,因为域实体的主要责任是关注其生命周期和身份,而IS在大多数情况下并不是管理这两项任务(即关注生命周期和身份)的组成部分

(b)

您仍然可以将IS传递给域实体方法并解决问题 这里不会违反PI,因为您正在传递一个接口,
不是一个实现。如果 域方法在IS接口上仅使用了一个方法

I-但在您之前的几篇帖子中,您注意到将IS作为域实体方法的参数传递是可以的,但您在这里说,如果此域方法在IS实例上仅使用一个方法,则会违反SRP

II-如果<强> 实现了一个包含单个方法的基于角色的接口,而是将这个基于角色的接口作为一个参数传递给域方法,您还会认为这是违反SRP的吗?若否,原因为何

(d)

PI通过使用接口进行维护

我读过好几次,即使域方法通过接口引用存储库,它仍然被认为违反了PI。你为什么不同意呢

(二)

不过,最好是非常明确。因此,与其通过考试 并隐式理解它恰好提供了 服务,将提供的功能声明为其自己的功能 接口,并使实体依赖于该接口

a) 所以,不将域服务注入域实体的唯一原因是因为违反了SRP

(b)

将提供的功能声明为其自己的接口

我想你是建议使用基于角色的界面?但是,甚至向域实体中注入基于角色的接口(比如说域服务)都不会导致违反SRP吗?因为正如您在1a中所指出的,注入的功能很可能只用于域实体的单个行为

看来你和Aaron Hawkins在将IS传递给域实体的方法方面是对立的

第三次更新:

(一)

(a)

所以,如果我理解正确的话-注入是到域服务DS中的 不会违反SRP,因为DS正在使用它执行其指定的 任务(即其指定的职责),同时注入 域实体违反了SRP,因为 域实体关注其生命周期和身份,ISmost 《时代周刊》并不是管理这两项任务(即 关注生命周期和身份

是的,这是正确的,也是主要原因之一

我-从
class TransferService
{
         public bool Transfer(IRepository repo)
         {
            var info = repo.Get...;
              ...
         } 
} 
class Foo
{
       ...

       public int DoSomething()
       {
            var info = TransferService.Transfer(...);
              ...
       }
}
class Dog
{
            ...
       void DoBark();
       void DoFetch();
       void DoGuard();

       Breed    GetBreed();
       Pedigree GetPedigree();
       Snack    FavSnack();
}
class Dog
{
            ...
       void DoBark();
       void DoFetch();
       void DoGuard();

       Breed    Breed { get{...} }
       Pedigree Pedigree { get{...} }
       Snack    Snack { get{...} }
}
ISomeAggregateRepository repository = //TODO: Construct repository and load it with the de-hydrated aggregates you intend to work with under your scope.
foreach (SomeAggregate someAggregate in repository) //The repository functions like an in memory collection.
{
    someAggregate.DoSomethingCool(); //The domain aggregate would expose an event to let the repository know that this method has been called and that the instance should be saved afterwards. (mimicking saving to a reference)
}
ISomeDomainService service = new ConcreteInfrastructuralSpecificDomainService();
service.DoSomethingCool(SomeAggregate target); //Send the aggregate to the domain service, not the other way around.