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

Leo*_*ves 4 php laravel laravel-5

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

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

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

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

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

所以,在Laravel 5.0中,似乎你能够绑定一些类,比如说FooBar一个键虽然被推荐为类名,但可能会有所不同,例如:

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

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

$fooBar = $this->app->make('myfoobarclass');
Run Code Online (Sandbox Code Playgroud)

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

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

Mar*_*ean 8

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

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

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

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

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

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

关于Laravel文档的Façade类参考部分,有两种方法可以解析应用程序中的服务.

  1. 您可以在" 类"列中键入提示,即Illuminate\Contracts\Hashing\Hasher
  2. 或者,您可以使用Service Container Binding列中的app()->make('hash')方法和方法.这些只是类名的"别名".

希望这可以帮助!