在已经使用构造函数参数时,如何在Laravel中依赖注入?

时间:2018-02-14 20:01:56

标签: php laravel dependency-injection constructor-injection

这是一个针对Laravel for PHP的问题。

abstract class AbstractClass
{
    protected $value1;
    protected $value2;
    protected $value3;

    public function __construct($value1, $value2, $value3) 
    {
        $this->value1 = $value1;
        $this->value2 = $value2;
        $this->value3 = $value3;
    }
}

class ClassToBeInjected
{
    public function doSomething() {}
}

class ClassOne extends AbstractClass
{
    public function __construct($value1, $value2, $value3) 
    {
        parent::__construct($value1, $value2, $value3);
    }
}

class ClassTwo extends AbstractClass
{
    public function __construct($value1, $value2, $value3) 
    {
        parent::__construct($value1, $value2, $value3);
    }
}

您好。看看上面的例子。我有两个类,ClassOne和ClassTwo,它们都扩展了AbstractClass。我希望这两个类都能够使用doSomething()

中的ClassToBeInjected

现在我真正的问题是,当我已经使用构造函数时,如何注入类?想象一下,我有一个调用ClassOne或ClassTwo的服务:new ClassOne(1, 2, 3);

我不能只将'ClassToBeInjected'添加到签名中,因为这会弄乱我的类型,使它看起来需要手动传入。同事建议在抽象类上使用特征,但似乎对我来说有点奇怪。 Laravel IRC上有人建议我这样做:

abstract class AbstractClass
{
    protected $value1;
    protected $value2;
    protected $value3;
    protected $injectedClass;

    public function __construct($value1, $value2, $value3)
    {
        $this->value1        = $value1;
        $this->value2        = $value2;
        $this->value3        = $value3;
        $this->injectedClass = app()->make(ClassToBeInjected::class);
    }
}

此示例有效,我可以忍受它。但是我不确定它是否是正确的方法,如果以后可能会导致任何问题,那就这样做。

1 个答案:

答案 0 :(得分:1)

您需要将注入的参数放在构造函数参数之前:

class ClassWithInjections {
    public function __construct(FirstClassToBeInjected $class1, SecondClassToBeInjected $class2, $parameter1, $parameter2) {

    }
}

然后要使用你的课程,你必须在app容器中进行:

$instance = app()->make(ClassWithInjections::class, ['parameter1value', 'parameter2value'])

此功能没有详细记录,但Controllers Dependency Injection Documentation上有一个示例说明:

  

您仍然可以键入提示Illuminate\Http\Request并访问您的   id参数通过定义控制器方法如下:

/**
 * Update the given user.
 *
 * @param  Request  $request
 * @param  string  $id
 * @return Response
 */
public function update(Request $request, $id)
{
    //
}

因为控制器方法也由Service Container解决,所以我认为同样适用于任何注射。阅读app()->make()方法,您会发现这是真的。