beerbuddha's avatar

Dependency Injection from Singleton not working

I'm using Cviebrock\LaravelElasticsearch within Lumen 5.2

which I have registered in the AppServiceProvider: $this->app->register(\Cviebrock\LaravelElasticsearch\LumenServiceProvider::class);

which registers:

        $app->singleton('elasticsearch', function ($app) {
            return new LumenManager($app, $app['elasticsearch.factory']);
        });

In the route.php

I can (and it worked) if I do the following: $elasticSearch = $app['elasticsearch'];

However inside the controller I must do this:

    public function __construct()
    {
        $this->elasticsearch = app('elasticsearch');
    }

If I try to type hint:

    public function __construct(\Cviebrock\LaravelElasticsearch\LumenManager $es)
    {
        $this->elasticsearch = $es;
    }

it squawks:

BindingResolutionException in Container.php line 839:
Unresolvable dependency resolving [Parameter #0 [ <required> $app ]] in class Cviebrock\LaravelElasticsearch\LumenManager

My goal is to try to make dependency injection happen for the controller instead of using app() call. Now I'm unsure if this is even possible but I thought it could happen so I can type hint and be able to inject but due to the error this went over my head and I need some help, understanding what I am doing wrong.

Thanks

0 likes
7 replies
spekkionu's avatar

If you want the auto-resolution to happen you need to bind using the fully qualified classname.

$app->singleton('Cviebrock\LaravelElasticsearch\LumenManager', function ($app) {
    return new LumenManager($app, $app['elasticsearch.factory']);
});
beerbuddha's avatar

@spekkionu Unfortunately the binding is done from the vendor package. Short from creating an issue request. Is my only option is to rewrite my own service provider to ensure proper binding?

spekkionu's avatar
Level 48

You can always add a binding that pulls from the existing one.

$app->bind('Cviebrock\LaravelElasticsearch\LumenManager', function ($app) {
    return $app['elasticsearch'];
});
1 like
beerbuddha's avatar

@spekkionu thanks for enlightening me. Its working I placed it in the bootstrap/app.php file.

Would you put it there, or would you bind it somewhere else?

spekkionu's avatar

app/Providers/AppServiceProvider.php would probably be a better place.

mistajolly's avatar

Alternatively, using the register() function in a ServiceProvider you can achieve this with the singleton method.

$this->app->singleton(SomeClass::class, SomeClass::class);

Please or to participate in this conversation.