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


Laravel 5.1 service container: Binding using something other than the class name?

这是一个很长的问题,但还是要问。关于Laravel 5.1中服务容器的一些文档,我有点困惑。我将首先解释我目前对容器的理解,然后解释我的困惑是从哪里产生的。

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

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

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

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

所以,在Laravel 5.0中,似乎你能够绑定一些类,说FooBar到一个键,虽然建议作为类名,可能是不同的东西,所以例如:

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

然后你可以使用:

来解析这个类
$fooBar = $this->app->make('myfoobarclass');

然而,这将使您无法使用类型提示解析该类,我猜这就是为什么5.1的文档特别声明使用类名的原因。然而,在facade部分(http://laravel.com/docs/5.1/facades#facade-class-reference)中,他们列出了facade以及它们的"服务容器绑定键",这与它们的类名不同。这是否意味着您不能使用类型提示来解析这些facade ?为什么要将绑定注册为类名以外的名称呢?或者这个文档只是过时了?

如果有人能说明这种不一致背后的原因,那将是惊人的,提前感谢。

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

$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文档中的farade类参考部分,有两种方法来解决应用程序中的服务。

  1. 您可以在Class列的值上键入提示,即Illuminate'Contracts'Hashing'Hasher
  2. 或者,您可以使用服务容器绑定列中的app()->make('hash')方法。这些只是类名的"别名"。

希望这对你有帮助!