Yahya Uddin
Yahya Uddin

Reputation: 28861

Laravel: Different implementations on an instance with Servcie Container

In Laravel, how do I resolve 2 different singleton implementations of an instance using Laravel's Service Container (https://laravel.com/docs/5.7/container).

For example, the 2 implementations I have for a Foo class is:

$this->app->singleton(Foo::class, function ($app) {
    return new Foo(config('services.foo.apiKey1'));
});

and

$this->app->singleton(Foo::class, function ($app) {
    return new Foo(config('services.foo.apiKey2'));
});

I then have to also resolve it somehow:

$fooV1 = app(Foo::class); // ?
$fooV2 = app(Foo::class); // ?

What is the correct way of writing and resolving 2 different singleton implementations of an instance?

Update

One solution I tried is as follows:

$this->app->singleton(Foo::class, function ($app, $parameters) {
    dump('Creating...'); // For testing only to see is actually a singleton
    $apiKey = $parameters[0] ? config('services.foo.apiKey1') : config('services.foo.apiKey2');
    return new Foo($apiKey);
});

and then resolve like so:

$fooV1 = app(Foo::class, [true]);
$fooV2 = app(Foo::class, [false]);

The above also correctly outputs:

Creating...
Creating...

As this is 2 different singletons.

This works for the most part. However, the singleton aspect is not respected. i.e. when creating the same foo twice:

$aV1 = app(Foo::class, [true]);
$bV1 = app(Foo::class, [true]);

Outputs:

Creating...
Creating...

It should have only outputted Created... once in this case, as a Foo with the same set of parameters was already created, thus not being a singleton.

Upvotes: 0

Views: 169

Answers (1)

Gozbeth Stanslaus
Gozbeth Stanslaus

Reputation: 121

Binding A Singleton

   $this->app->singleton('foo1', function ($app) {
     return new Foo(config('services.foo.apiKey1'));
   });

    $this->app->singleton('foo2', function ($app) {
        return new Foo(config('services.foo.apiKey2'));
     });

Instead of passing the Foo::class on the first parameter pass the name that you will be using to resolve that singleton you are creating

To resolve do the following

//a new instance of Foo is created 
$foo1 = $this->app->make('foo1'); 

//the same instance created before is returned
$foo2 = $this->app->make('foo2');

Let me know if i helped

Upvotes: 1

Related Questions