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

How do I dependency inject in Laravel when already using constructor params?

这是一个针对 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);
    }
}

你好。看看上面的例子。我有两个 classes,ClassOne 和 ClassTwo,它们都扩展了 AbstractClass。我希望这两个 classes 都能够使用 ClassToBeInjected

中的 doSomething()

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

我不能只在签名中添加“ClassToBeInjected”,因为这会弄乱我的类型提示,让它看起来需要手动传入。一位同事建议在摘要中使用特征 class,但这对我来说似乎有点奇怪。 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);
    }
}

这个例子有效,我可以接受。但是我不确定它是否是正确的方法,以及这样做以后是否会引起任何问题。

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

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

    }
}

然后要使用您的 class,您必须将其放入应用程序容器中:

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

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

You may still type-hint the Illuminate\Http\Request and access your id parameter by defining your controller method as follows:

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

因此,由于控制器方法也由 Service Container, I've assumed that the same will work for any injections. Reading the app()->make() 方法解析,您会发现这是真的。