扩展类时的构造函数注入

dbr*_*ann 8 php oop dependency-injection symfony

这个问题与Symfony 2没有严格的关系,但是当我使用Symfony 2组件并且稍后可能使用Symfony\Component\DependencyInjection\Container作为DI-Container时,它可能是相关的.

我目前正在使用Symfony 2中的组件构建一个小型库,例如HttpFoundation,Validator,Yaml.我的域服务都扩展了一个基本的AbstractService,只提供了Doctrine\ORM\EntityManager和Symfony\Component\Validator\Validator,它们通过构造函数注入,如下所示:

abstract class AbstractService
{
    protected $em;

    protected $validator;

    /**
     * @param Doctrine\ORM\EntityManager $em
     * @param Symfony\Component\Validator\Validator $validator
     */
    public function __construct(EntityManager $em, Validator $validator)
    {
        $this->em = $em;
        $this->validator = $validator;
    }
}
Run Code Online (Sandbox Code Playgroud)

扩展此AbstractService的Service类现在可能需要注入其他组件,例如Symfony\Component\HttpFoundation\Session.从我这样做:

class MyService extends AbstractService
{
    /**
     * @var Symfony\Component\HttpFoundation\Session
     */
    protected $session;

    /**
     * @param Symfony\Component\HttpFoundation\Session $session
     * @param Doctrine\ORM\EntityManager $em
     * @param Symfony\Component\Validator\Validator $validator
     */
    public function __construct(Session $session, EntityManager $em, Validator $validator)
    {
        parent::__construct($em, $validator);
        $this->session = $session;
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有更优雅的方法来解决这个问题,而不必重复父的构造函数参数,例如通过使用Setter-Injection for Session?

在我看来,当我使用Setter-Injection for Session时,我必须在我的方法中访问它之前添加检查,是否已经注入,我想避免.另一方面,我不想"重复"注入所有服务共享的基本组件.

Gor*_*don 3

另一种选择是不从抽象类型扩展您的服务。将抽象类型更改为真实的类,然后将其注入到您的服务中,例如

\n\n
class MyService\n\xe2\x80\xa6\n    public function __construct(ServiceHelper $serviceHelper)\n    {\n        $this->serviceHelper = $serviceHelper;\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

另一种选择是在需要依赖项之前不传递依赖项,例如

\n\n
class MyService\n\xe2\x80\xa6\n    public function somethingRequiringEntityManager($entityManager)\n    {\n        // do something with EntityManager and members of MyService\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n