Reputation: 28861
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
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