Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly inject dependency into Laravel artisan command?

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

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:

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.

like image 849
Ren Avatar asked Mar 14 '14 11:03

Ren


1 Answers

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

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.

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');
like image 70
alexrussell Avatar answered Sep 19 '22 04:09

alexrussell