Как правильно вводить зависимость в команду мастеров Laravel?

В принципе, я хочу вызвать метод в репозитории Repository.php из команды laravel.

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

Я ожидаю интерфейс в конструкторе команд, а затем установите его в защищенную переменную.

В поставщике услуг я привязываю класс Interface to Repository.

Прямо сейчас, в start/artisan.php, я просто пишу:

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

Можно ли использовать интерфейс здесь? Каков правильный путь? Я смущен.

Спасибо заранее.

EDIT: для пояснения это работает только так, как сейчас, но я не хочу жестко указывать конкретный класс при регистрации команды artisan.

Ответ 1

Вы можете использовать автоматические инъекции для инъекций контейнера IoC:

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

Если конструктор ExampleCommand принимает конкретный класс в качестве его параметра, он будет введен автоматически. Если он использует интерфейс, вам нужно сообщить контейнеру IoC использовать конкретный конкретный класс всякий раз, когда запрашивается данный интерфейс.

Конкретный (для краткости игнорируйте пространства имен):

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

Artisan::resolve('ExampleCommand');

Интерфейс (для краткости игнорируем пространства имен):

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

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

Ответ 2

Вы можете использовать interface в конструкторе, чтобы ввести подсказку зависшего объекта, но вам нужно привязать конкретный класс к интерфейсу в контейнере IoC, используя что-то вроде следующего, так что это сработает.

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

Подробнее о документации.