在Laravel中,如何使用Laravel的服务容器(https://laravel.com/docs/5.7/container)解决实例的2种不同的单例实现。
例如,我为Foo
类提供的2种实现是:
$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); // ?
编写和解决实例的2种不同单例实现的正确方法是什么?
更新
我尝试过的一种解决方案如下:
$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个不同的单例。
这在大多数情况下都有效。但是,不尊重单例方面。即两次创建相同的foo时:
$aV1 = app(Foo::class, [true]);
$bV1 = app(Foo::class, [true]);
输出:
Creating...
Creating...
在这种情况下,它应该只输出一次Created...
,因为已经创建了具有相同参数集的Foo,因此不是单例。
答案 0 :(得分: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');
让我知道我是否帮忙