#laravel #laravel-5 #dependency-injection #laravel-5.7
#laravel #laravel-5 #внедрение зависимостей #laravel-5.7
Вопрос:
В Laravel, как мне разрешить 2 разные одноэлементные реализации экземпляра с использованием контейнера-сервиса Laravel (https://laravel.com/docs/5.7/container ).
Например, 2 реализации, которые у меня есть для Foo
класса, являются:
$this->app->singleton(Foo::class, function ($app) {
return new Foo(config('services.foo.apiKey1'));
});
и
$this->app->singleton(Foo::class, function ($app) {
return new Foo(config('services.foo.apiKey2'));
});
Затем мне также нужно как-то это решить:
$fooV1 = app(Foo::class); // ?
$fooV2 = app(Foo::class); // ?
Каков правильный способ написания и разрешения двух разных одноэлементных реализаций экземпляра?
Обновить
Одно из решений, которое я попробовал, заключается в следующем:
$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);
});
а затем разрешить следующим образом:
$fooV1 = app(Foo::class, [true]);
$fooV2 = app(Foo::class, [false]);
Приведенное выше также корректно выводит:
Creating...
Creating...
Поскольку это 2 разных синглета.
Это работает по большей части. Однако аспект singleton не соблюдается. т.Е. при создании одного и того же foo дважды:
$aV1 = app(Foo::class, [true]);
$bV1 = app(Foo::class, [true]);
Выводит:
Creating...
Creating...
В этом случае он должен был выводиться только Created...
один раз, поскольку Foo с тем же набором параметров уже был создан, таким образом, не являясь синглтоном.
Ответ №1:
Привязка синглтона
$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'));
});
Вместо передачи Foo::class в первом параметре передайте имя, которое вы будете использовать для разрешения создаваемого вами синглтона
Для решения проблемы выполните следующее
//a new instance of Foo is created
$foo1 = $this->app->make('foo1');
//the same instance created before is returned
$foo2 = $this->app->make('foo2');
Дайте мне знать, если я помог