Php 域规范对象的存储库接口的依赖项注入
不确定我是否太累了,错过了什么,所以提前道歉 我有一个php域,我需要对其进行重组,因为使用服务的模型很贫乏。这是因为我没有使用Doctrine,而是使用Laravel的雄辩作为我的映射器(原因是链接到其他不同的DB服务器类型) 我的审查结构需要与此类似:(本例中我只包括几件事) 模板实体的TemplateName为VO。 TemplateName必须满足2个规范。长度必须超过3个字符,并且必须是唯一的 我使用TemplateRepositoryInterface来检查唯一性,并且该接口在服务提供者中有一个有说服力的实现 因此,模板实体有一个方法:Php 域规范对象的存储库接口的依赖项注入,php,laravel,dependency-injection,domain-driven-design,ddd-repositories,Php,Laravel,Dependency Injection,Domain Driven Design,Ddd Repositories,不确定我是否太累了,错过了什么,所以提前道歉 我有一个php域,我需要对其进行重组,因为使用服务的模型很贫乏。这是因为我没有使用Doctrine,而是使用Laravel的雄辩作为我的映射器(原因是链接到其他不同的DB服务器类型) 我的审查结构需要与此类似:(本例中我只包括几件事) 模板实体的TemplateName为VO。 TemplateName必须满足2个规范。长度必须超过3个字符,并且必须是唯一的 我使用TemplateRepositoryInterface来检查唯一性,并且该接口在服务提
public function create()
{
if ($this->meetsTemplateNameSpecification())
{
//fire events etc... saving to repo is done one step above from a service that call this class and gets $this to send tot he interface
return $this;
}
throw new InvalidArgumentException("Template name is not valid.");
}
然后我的meetsTemplateNameSpecification方法:
private function meetsTemplateNameSpecification($originalTemplateName = null)
{
$templateNameSpecification = new TemplateNameSpecification($this->name, $originalTemplateName);
if($templateNameSpecification->isMet())
{
return true;
}
return false;
}
在这次重组之前,一个服务启动了所有这些,并将RepositoryInterface传递给他们,这样做很容易。然而,这种方式我不知道如何和/或在哪里传递或注入接口,因为如果我将接口从容器注入到规范类,那么我无法从实体启动,也无法将规范类注入实体,因为我希望能够使用它的构造函数
我发现在PHP和ActiveRecord中很难保持关注点的分离,也很难在域中不依赖持久性
有人有更好的结构吗?如果你需要更多的代码,请告诉我。
到目前为止,我想到的唯一解决方案是在我的规范对象中有静态方法,这样它们就不需要启动,并且我可以从容器中注入Repo依赖项。这是一种方法,还是有更好的方法可以使用PHP。我也讨厌从容器注入到域中,但我认为没有更好的方法,除非您使用的是不同的体系结构。我认为您过于复杂了 如果在以规范为参数的非常通用的方法签名中使用规范模式,或者如果您有一整套规范,那么规范模式是很酷的。只需测试一两个特定条件,这可能是过火了
此外,尝试将存储库注入域对象(我猜您是这样)可能会给您带来更多的麻烦。字符串长度很可能不是域规则和唯一性。您最好在应用程序服务(或控制器)级别检查这些约束,直接调用那里的存储库以获得唯一性,这样可以省去所有注入的麻烦。谢谢。对不起,我解释得不够好。我使用这些作为所有域规则的简单示例。这些只是基本规则(唯一性除外,唯一性必须是业务规则)。别担心,我在其他层中有几个验证。域本身有几个其他重要的规则,这只是对象的一个上下文。我的问题不是关于模式,而是关于实现。这有意义吗?问题是…如何避免模型依赖于存储库或尽可能地最小化。如果可以完全避免,那么很好:)根据我的经验,95%的域规则您不需要存储库,因为它们是关于单个聚合的,聚合根目录可以执行它们。5%的域逻辑可能发生在给定聚合之外(主要在域服务中)但是,您可以再次向服务传递它所需的域对象,而不是存储库。谢谢,但正如您所看到的,此规则特别依赖于存储库,因为它必须检查名称是否存在于其中。这显然是一个简单的示例,另一个示例是从外部数据库检查客户的UID。我想我更愿意依赖我的repo接口而不是服务。在我看来,从外部数据库检查客户的UID根本不像域内容。如果您真的想在域内强制实施名称唯一性,我建议您在域服务中这样做。