Laravel 5.1服务容器:使用类名以外的东西进行绑定?

时间:2015-07-28 19:06:29

标签: php laravel laravel-5

一个冗长的问题,但是这里有。关于Laravel 5.1中服务容器的一些文档,我有点困惑。我先解释一下我目前对容器的理解,然后解释我的混乱局面。

所以,我很确定我理解了向服务容器注册绑定的过程。要引用文档,请使用bind方法注册绑定,传递我们希望注册的类或接口名称以及返回类实例的Closure:

$this->app->bind('HelpSpot\API', function ($app) {
    return new HelpSpot\API($app['HttpClient']);
});

现在,在Laravel 5.0文档中,实际上略有不同:

  

Closure解析器在容器中注册了一个键(通常是类名)和一个返回一些值的Closure。

所以,在Laravel 5.0中,似乎你能够绑定一些类,比如说FooBar到一个键,虽然建议它是类名,但可能会有所不同,例如:

$this->app->bind('myfoobarclass', function($app) {
    return new FooBar($app['SomethingElse']);
});

然后您可以使用以下方法解决该课程:

$fooBar = $this->app->make('myfoobarclass');

然而,这将删除你的能力ro使用类型提示解决该类,我猜这是为什么5.1的文档具体使用类名称。但是,在Facades(http://laravel.com/docs/5.1/facades#facade-class-reference)部分中,他们列出了外观及其“服务容器绑定密钥”,这与其类名不同。这是否意味着您无法使用类型提示解决这些外观?他们为什么要将他们的绑定注册为他们的类名以外的东西?或者这个文件是否过时了?

如果有人能够对这种不一致的原因有所了解,那将是惊人的,提前谢谢。

1 个答案:

答案 0 :(得分:7)

您通常将实现绑定到接口。因此,不是通过类的名称向服务容器添加内容,而是使用它实现的接口的名称:

$this->app->bind('App\HttpClientInterface', function ($app) {
    return new \Guzzle\HttpClient;
});

然后,您可以在应用程序中键入提示HttpClientInterface接口,而是获取绑定的GuzzleHttpClient实例。这使您可以在一个地方交换实现,而无需重新编写应用程序代码。

您不限于使用完全限定的类/接口名称,如果您愿意,可以使用任意字符串作为键名:

$this->app->bind('http.client', function () {
    return new \Guzzle\HttpClient;
});

但你不能在这些上打字提示;这是您使用app()->make('http.client')方法的地方。

关于Laravel文档的Façade Class Reference部分,有两种方法可以解析您应用中的服务。

  1. 您可以在列中键入提示,即Illuminate\Contracts\Hashing\Hasher
  2. 或者,您可以使用app()->make('hash')方法使用服务容器绑定列中的内容。这些只是类名的“别名”。
  3. 希望这有帮助!