Pregunta

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.

¿Fue útil?

Solución

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');

Otros consejos

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

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

Read more on the documentation.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top