Внедрение класса в другой класс

У меня есть класс InjectedClass с методом someMethod. Класс принимает три параметра. Мне нужен вывод метода в другом классе, Myclass. По сути, мне нужно передать те же три параметра через конструктор в Myclass во внедренный класс, чтобы он вернул некоторые данные.

Проблема в том, что я получаю сообщение об ошибке, что четвертый параметр (внедренный класс) в конструкторе Myclass должен быть экземпляром вложенного класса, но он пуст! См. Пример.

Я думаю, проблема в том, что класс Injected инициализируется без параметров, следовательно, не инициализируется и поэтому пуст. Кроме того, я получаю более или менее тот же результат, если пытаюсь внедрить класс непосредственно в метод myfunction. Как решить этот бардак?

class Myclass {

    private $var1;
    private $var2;
    private $var3;
    private $injectedclass;

    public function __construct($var1, $var2, $var3, InjectedClass $injectedclass)
    {
        $this->var1 = $var1;
        $this->var2 = $var2;
        $this->var3 = $var3;
        $this->injectedclass = $injectedclass;
    }

    public function myfunction()
    {
        return $this->injectedclass($this->var1, $this->var2, $this->var3)->someMethod();
    }
}

class InjectedClass {

    private $var1;
    private $var2;
    private $var3;

    public function __construct($var1, $var2, $var3)
    {
        $this->var1 = $var1;
        $this->var2 = $var2;
        $this->var3 = $var3;
    }

    public function someMethod()
    {
        // do stuff
    }
}

person Rastur    schedule 19.09.2014    source источник
comment
как ты звонишь Myclass ?   -  person cmorrissey    schedule 20.09.2014
comment
$myclass = новый Myclass($var1, $var2, $var3);   -  person Rastur    schedule 20.09.2014


Ответы (3)


MyClass нужен только 1 параметр в конструкции — экземпляр InjectedClass, который готов к работе. т.е.

$injected = new Injected($var1, $var2, $var);

$my = new MyClass($injected);

$my->myfunction(); // will work correctly now
person Angel Iliikov    schedule 19.09.2014

Я бы переосмыслил, как вы пытаетесь использовать инъекцию зависимостей. Самый простой метод, который мне приходит в голову, - это создать сеттеры в InjectedClass и установить их, когда вы устанавливаете переменную класса в конструкции. Что-то типа:

class Myclass {

    private $var1;
    private $var2;
    private $var3;
    private $injectedclass;

    public function __construct($var1, $var2, $var3, InjectedClass $injectedclass)
    {
        $this->var1 = $var1;
        $this->var2 = $var2;
        $this->var3 = $var3;
        $this->injectedclass = $injectedclass;
        $this->injectedclass->setParams($this->var1, $this->var2, $this->var3);
    }

    public function myfunction()
    {
        return $this->injectedclass($this->var1, $this->var2, $this->var3)->someMethod();
    }
}

class InjectedClass {

    private $var1;
    private $var2;
    private $var3;

    public function setParams($var1, $var2, $var3) {
        $this->var1 = $var1;
        $this->var2 = $var2;
        $this->var3 = $var3;
    }

    public function someMethod()
    {
        // do stuff
    }
}

Конечно, вы можете немного почистить это, но, сделав инъекцию таким образом, вы сможете избежать проблемы, с которой столкнулись.

person Cameeob2003    schedule 19.09.2014

Все зависит от того, чего вы хотите достичь, но в основном в

public function myfunction()
{
   return $this->injectedclass($this->var1, $this->var2, $this->var3)->someMethod();
}

вам не нужно передавать эти параметры, потому что $this->injectedclass уже является объектом, который уже инициализировал свои свойства. Итак, код должен выглядеть так:

class Myclass {

    private $var1;
    private $var2;
    private $var3;
    private $injectedclass;

    public function __construct($var1, $var2, $var3, InjectedClass $injectedclass)
    {
        $this->var1 = $var1;
        $this->var2 = $var2;
        $this->var3 = $var3;
        $this->injectedclass = $injectedclass;
    }

    public function myfunction()
    {
        return $this->injectedclass->someMethod();
    }
}

class InjectedClass {

    private $var1;
    private $var2;
    private $var3;

    public function __construct($var1, $var2, $var3)
    {
        $this->var1 = $var1;
        $this->var2 = $var2;
        $this->var3 = $var3;
    }

    public function someMethod()
    {
        // do stuff
        echo $this->var1.' '.$this->var2.' '.$this->var3."<br />";
    }
}

$m = new Myclass(1,2,3, new InjectedClass(1,2,3));
$m->myFunction();

Однако, как вы видите, когда вы создаете экземпляр Myclass, вам нужно передать аргументы 1,2,3 как Myclass, так и InjectedClass, и если эти значения одинаковы, это может быть не очень удобно.

Таким образом, вы можете изменить свой код на:

class Myclass {

    private $var1;
    private $var2;
    private $var3;
    private $injectedclass;

    public function __construct($var1, $var2, $var3, InjectedClass $injectedclass)
    {
        $this->var1 = $var1;
        $this->var2 = $var2;
        $this->var3 = $var3;
        $this->injectedclass = $injectedclass;
        $this->injectedclass->setParams($var1, $var2, $var3);
    }

    public function myfunction()
    {
        return $this->injectedclass->someMethod();
    }
}

class InjectedClass {

    private $var1;
    private $var2;
    private $var3;

    public function setParams($var1, $var2, $var3)
    {
        $this->var1 = $var1;
        $this->var2 = $var2;
        $this->var3 = $var3;
    }

    public function someMethod()
    {
        // do stuff
        echo $this->var1.' '.$this->var2.' '.$this->var3."<br />";
    }
}

$m = new Myclass(1,2,3, new InjectedClass());
$m->myFunction();

поэтому вы передаете аргументы только Myclass, а он устанавливает аргументы в InjectedClass. Но этот метод приводит к тому, что даже если вы создаете объект класса InjectedClass, вам нужно будет запустить метод setParams также для установки параметров, поэтому это не лучшее решение.

Лучше бы было:

class Myclass {

    private $var1;
    private $var2;
    private $var3;
    private $injectedclass;

    public function __construct(InjectedClass $injectedclass)
    {
        $this->injectedclass = $injectedclass;
        list ($this->var1, $this->var2, $this->var3) = $this->injectedclass->getParams();
    }

    public function myfunction()
    {
        return $this->injectedclass->someMethod();
    }
}

class InjectedClass {

    private $var1;
    private $var2;
    private $var3;

    public function __construct($var1, $var2, $var3)
    {
        $this->var1 = $var1;
        $this->var2 = $var2;
        $this->var3 = $var3;
    }

    public function getParams() {
        return array ($this->var1, $this->var2, $this->var3);
    }

    public function someMethod()
    {
        // do stuff
        echo $this->var1.' '.$this->var2.' '.$this->var3."<br />";
    }
}

$m = new Myclass(new InjectedClass(1,2,3));
$m->myFunction();

где объект InjectedClass может возвращать эти параметры объекту Myclass.

person Marcin Nabiałek    schedule 20.09.2014