域规范对象的存储库接口的依赖项注入


Dependency Injection of Repository Interface for a Domain Specification Object

不确定我是不是太累了,错过了什么,所以提前道歉。

我有一个php域,我需要对其进行重组,因为它最终使用了一个贫血的服务模型。这是因为我没有使用Doctrine,而是使用Laravel的Eloquent作为我的映射器(原因是链接到其他不同的DB服务器类型)

我审查过的结构需要类似于这样做:(我只为这个例子包括了几件事)

模板实体的TemplateName为VO。TemplateName必须满足2个规范。长度必须超过3个字符,并且必须是唯一的。

我使用TemplateRepositoryInterface来检查唯一性,并且该接口有一个以服务提供商为界的Eloquent实现。

因此,模板实体有一种方法:

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传递给它们,所以这很容易。然而,通过这种方式,我不知道如何和/或在哪里传递或注入接口,因为如果我将接口从容器注入到Specification类,那么我就无法从Entity启动,也无法将Spec类注入到实体,因为我希望能够使用它的构造函数。

我发现在PHP和Active Record中很难保持关注点的分离,并且不依赖于域中的持久性。

有人有更好的结构吗?如果你需要更多的代码,请告诉我。到目前为止,我想到的唯一解决方案是在我的规范对象中有静态方法,这样它们就不需要启动,并且我可以从容器中注入Repo依赖项。这是正确的方法,还是有更好的方法来使用PHP。我也讨厌从容器注入到域,但我认为没有更好的方法,除非你使用不同的体系结构。

我觉得你把事情搞得太复杂了。

如果在一个以规范为参数的非常通用的方法签名中使用规范模式,或者如果您有一个完整的规范家族,那么规范模式是很酷的。只有一两个特定的条件需要测试,这可能有些过头了。

此外,尝试将Repository注入域对象(我猜你是这样)可能会给你带来更多的麻烦而不是好处。字符串长度很可能不是域规则,唯一性也可能不是。您最好在应用程序服务(或控制器)级别检查这些约束,直接调用那里的存储库以获得唯一性,这将省去所有的注入麻烦。