Внедрение конструктора при расширении класса

Этот вопрос не имеет прямого отношения к Symfony 2, но поскольку я использую компоненты Symfony 2 и позже, вероятно, буду использовать Symfony \ Component \ DependencyInjection \ Container в качестве DI-контейнера, это может быть актуальным.

В настоящее время я создаю небольшую библиотеку, используя компоненты из Symfony 2, например. HttpFoundation, Валидатор, Ямл. Все мои доменные службы расширяют базовую службу AbstractService, не предоставляя ничего, кроме Doctrine \ ORM \ EntityManager и Symfony \ Component \ Validator \ Validator через Constructor-Injection следующим образом:

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;
    }
}

Классу службы, расширяющему эту службу AbstractService, теперь может потребоваться внедрение дополнительных компонентов, например 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;
    }
}

Есть ли более элегантный способ решить эту проблему без повторения аргументов родительского конструктора, например используя вместо этого Setter-Injection для Session?

Насколько я понимаю, когда я использую Setter-Injection для Session, я должен добавить проверки, прежде чем обращаться к нему в моих методах, независимо от того, введено ли оно уже, чего я хочу избежать. С другой стороны, я не хочу «повторять» введение базовых компонентов, общих для всех сервисов.

8
задан Gordon 7 February 2012 в 12:34
поделиться