如何正确地将依赖注入 Laravel artisan 命令?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22403226/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 09:11:32  来源:igfitidea点击:

How to properly inject dependency into Laravel artisan command?

phpdependency-injectionlaravellaravel-4ioc-container

提问by Ren

Basically I want to call a method on a repository Repository.php from a laravel command.

基本上我想从 laravel 命令调用存储库 Repository.php 上的方法。

Example\Storage\Repository.php
Example\Storage\RepositoryInerface.php
Example\Storage\RepositoryServiceProvider.php

I expect Interface in the command constructor and then set it to the protected variable.

我希望在命令构造函数中使用接口,然后将其设置为受保护的变量。

In the service provider I bind the Interface to Repository class.

在服务提供者中,我将接口绑定到存储库类。

Right now, in start/artisan.php I just write:

现在,在 start/artisan.php 我只写:

Artisan::add(new ExampleCommand(new Repository());

Can I use an interface here? What is the correct way? I am confused.

我可以在这里使用接口吗?正确的方法是什么?我很迷惑。

Thanks in advance.

提前致谢。

EDIT: To clarify, it only works the way it is now, but I don't want to hardcode a concrete class while registering the artisan command.

编辑:澄清一下,它只能按照现在的方式工作,但我不想在注册 artisan 命令时硬编码一个具体的类。

回答by alexrussell

You could use the automatic dependency injection capabiltiies of the IoC container:

您可以使用 IoC 容器的自动依赖注入功能:

Artisan::add(App::make('\Example\Commands\ExampleCommand'));
// or
Artisan::resolve('\Example\Commands\ExampleCommand');

If ExampleCommand's constructor accepts a concrete class as its parameter, then it'll be injected automatically. If it relies on the interface, you need to tell the IoC container to use a specific concrete class whenever the given interface is requested.

如果 ExampleCommand 的构造函数接受一个具体类作为其参数,那么它会被自动注入。如果它依赖于接口,则需要告诉 IoC 容器在请求给定接口时使用特定的具体类。

Concrete (ignoring namespaces for brevity):

具体(为简洁起见忽略命名空间):

class ExampleCommand ... {
    public function __construct(Repository $repo) {
    }
}

Artisan::resolve('ExampleCommand');

Interface (ignoring namespaces for brevity):

接口(为简洁起见忽略命名空间):

class ExampleCommand ... {
    public function __construct(RepositoryInterface $repo) {
    }
}

App::instance('RepositoryInterface', new Repository);
Artisan::resolve('ExampleCommand');

回答by The Alpha

You may use the interfacein the constructor to type hint the depended object but you have to bind the concrete class to the interface in the IoCcontainer using something like following, so it'll work.

您可以interface在构造函数中使用 来提示依赖对象,但您必须IoC使用类似以下内容将具体类绑定到容器中的接口,这样它就会起作用。

App::bind('Example\Storage\RepositoryInerface', 'Example\Storage\Repository');

Read more on the documentation.

阅读有关文档的更多信息