【问题标题】:Dependency Injection of Repository Interface for a Domain Specification Object域规范对象的存储库接口的依赖注入
【发布时间】:2015-04-01 20:16:55
【问题描述】:

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

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

我的审查结构需要与此类似:(我仅在此示例中包含几件事)

模板实体的模板名称为 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.");
    }

然后我的 meetTemplateNameSpecification 方法:

private function meetsTemplateNameSpecification($originalTemplateName = null)
    {
        $templateNameSpecification = new TemplateNameSpecification($this->name, $originalTemplateName);

        if($templateNameSpecification->isMet())
        {
            return true;
        }

        return false;
    }

在此重组之前,服务会启动所有这些并将 RepositoryInterface 传递给它们,因此这很容易。但是,这样我不知道如何和/或在哪里传递或注入接口,因为如果我将它从容器注入到规范类,那么我不能从实体启动,也不能将规范类注入实体要么是因为我希望能够使用它的构造函数。

我发现在 PHP 和 Active Record 中保持关注点分离和不依赖于域中的持久性非常困难。

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

【问题讨论】:

    标签: php laravel dependency-injection domain-driven-design ddd-repositories


    【解决方案1】:

    我认为你把事情复杂化了。

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

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

    【讨论】:

    • 谢谢。对不起,如果我解释得不够好。我将这些用作所有域规则的简单示例。这些只是基本规则(除了必须是业务规则的唯一性)。别担心我在其他层有几个验证。域本身还有其他几个重要规则,这只是对象的一个​​上下文。我的问题不是关于模式,而是关于实施。这有意义吗?问题是......如何避免模型依赖于存储库或尽可能减少。如果可以完全避免它,那就太好了:)
    • 根据我的经验,95% 的域规则不需要存储库,因为它们是关于单个聚合的,聚合根可以执行它们。
    • 5% 的域逻辑可能发生在给定的聚合之外(主要在域服务中),但是您可以再次向服务传递它需要的域对象,而不是存储库。
    • 谢谢,但正如您所见,这条规则特别依赖于存储库,因为它必须检查名称是否存在于其中。这显然是一个简单的例子,另一个例子是从外部数据库中检查客户的 UID。我想我宁愿依赖我的 repo 接口而不是服务。
    • 从外部数据库检查客户的 UID 对我来说根本不像域的东西。如果您真的想在域内强制执行名称唯一性,我建议您在域服务中执行此操作。
    猜你喜欢
    • 1970-01-01
    • 2023-03-05
    • 2018-05-02
    • 2017-06-10
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    • 2012-11-28
    相关资源
    最近更新 更多