Laravel:使用Servcie容器的实例上的不同实现

时间:2019-03-29 00:40:24

标签: laravel laravel-5 dependency-injection laravel-5.7

在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,因此不是单例。

1 个答案:

答案 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');

让我知道我是否帮忙