2015-11-23 4 views
2

Я пытаюсь ввести Artisan в сервис, поэтому я могу избежать использования фасада. Глядя на ссылках класса фасада я могу видеть, что класс я должен быть инъекционным является:Injecting Artisan in Service класс

Illuminate\Console\Application 

Поэтому я предположил бы, что делать это:

<?php 

namespace App\Service; 

use Illuminate\Console\Application; 

class DummyDataService 
{ 
    /** 
    * @var Application 
    */ 
    private $application; 

    public function __construct(
     Application $application 
    ) { 
     $this->application = $application; 
    } 

    public function insertDummyData() 
    { 
     $this->application->call('db:seed', [ 
      '--class' => 'DummyDataSeeder' 
     ]); 
    } 
} 

... будет работать. Тем не менее, я получаю следующее сообщение об ошибке:

BindingResolutionException in Container.php line 824: 
Unresolvable dependency resolving [Parameter #2 [ <required> $version ]] in class Illuminate\Console\Application 

Это работает, если я просто вызвать метод на фасаде, так как:

Artisan::call('db:seed', [ 
    '--class' => 'DummyDataSeeder' 
]); 

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

Заранее спасибо.

ответ

4

Вы должны вводить Illuminate\Contracts\Console\Kernel и не Illuminate\Console\Application добиться того, что вы хотите, так что ваш класс должен выглядеть следующим образом:

<?php 

namespace App\Service; 

use Illuminate\Contracts\Console\Kernel; 

class DummyDataService 
{ 
    private $kernel; 

    public function __construct(Kernel $kernel) 
    { 
     $this->kernel = $kernel; 
    } 

    public function insertDummyData() 
    { 
     $this->kernel->call('db:seed', [ 
      '--class' => 'DummyDataSeeder' 
     ]); 
    } 
} 
+0

Удивительно, это работает, поэтому я отметил правильный ответ. Спасибо за вашу помощь. – Steven1978

+1

Просто хотел проследить и сказать, что не только это решение работает, но и является полностью правильной ссылкой. Документы были фактически неправильными. Я исправил их в PR, который с тех пор был объединен, поэтому теперь все должно быть правильно для будущих людей, которые проверяют. –

1

Если вы заглядываете в конструктор для Illuminate\Console\Application, вы увидите, что он ожидает параметр $version и не предоставляет никаких настроек по умолчанию. Поэтому, если он явно не указан, он будет терпеть неудачу из-за этой зависимости. Честно говоря, это похоже на ошибку. Если вы посмотрите на родительский класс Symphony, вы увидите, что он предоставляет строку по умолчанию 'UNKNOWN' в своем конструкторе. Если вы измените Illuminate\Console\Application на то же значение по умолчанию, ваши команды в коде должны теперь работать.

Это дает вам два варианта.

  1. Просто используйте фасад Artisan для этого случая. Вы должны быть в порядке, используя инсталляцию конструктора для остальных фасадов, поскольку это непосредственно влияет на Artisan facade.
  2. Измените конструктор в исходном коде на значение по умолчанию. Не идеально, так как все ваши изменения будут потеряны при каждом обновлении Laravel, но это вариант. Возможно, вы сможете подготовить своего рода поставщика услуг, который вводит версию во все экземпляры Illuminate\Console\Application, но я не уверен.

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

+0

Да, это действительно кажется, что ошибка мне тоже. Спасибо за предложения. Я теперь вернусь к использованию фасада, но буду продолжать рыть. – Steven1978

Смежные вопросы