laravel 基础教程 —— 服务容器

一向绑定实例

您也可以行使 instance
方法来绑定3个曾经存在的实例对象到容器中。随后的拜访中,容器都会回到那么些给定的实例:

  $fooBar = new FooBar(new SomethingElse);

  $this->app->instance('FooBar', $fooBar);

容器事件

容器在历次解析贰个目的时都会接触2个风云,你可以由此 resolving
方法来监听这几个事件:

$this->app->resolving(function ($object, $app) {
  // Called when container resolves object of any type... 
});

$this->app->resolving(FooBar::class, function (FooBar $fooBar, $app) {
  // Called when container resolves objects of type "FooBar"... 
});

如你所看到的,resolving
方法中你可以传递二个回调函数,回调函数会接收三个参数,3个是分析拿到的靶子,2个是容器自个儿,那样您就可以在对象传递到买主之前增进一些外加的质量。

解析

laravel 提供了各种形式从劳动容器中分析出实例。首先,你可以使用 make
方法,它接受3个您想要解析的类依然接口:

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

附带,你也能够采用数组的点子从容器中分析对象,因为它完成了 PHP 的
ArrayAccess 接口:

$fooBar = $this->app['FooBar'];

说到底,也是最关键的,你也得以在类的构造函数中回顾的拔取‘类型指示’来从容器中分析倚重。控制器,事件监听器,队列职责,中间件等都帮忙这种方式。在实践中,那是大部分对象从容器中剖析的主意。

容器会自行的为类进行依赖的注入。比如,你可以在控制器的构造函数中对利用中定义的堆栈类举办项目提醒。仓库实例会自动的从容器中举行分析并流入到控制器中:

<?php

namespace App\Http\Controllers;

use App\Users\Repository as UserRepository;

class UserController extends Controller
{
  /**
   * The user repository instance.
   *
   */
   protected $users;

   /**
    * Create a new controller instance.
    *
    * @param UserRepository $users
    * @return void
    */
    public function __construct(UserRepository $users)
    {
      $this->users = $users;
    }

    /**
     * Show the user with the given ID.
     *
     * @param int $id
     * @return Response
     */
     public function show($id)
     {
       //
     }
}

绑定接口到贯彻

劳动容器具有一个极度强劲的性状就是可以绑定接口到给定的完毕。比如,让我们只要我们有
EventPusher 接口和 RedisEventPusher 达成。一旦大家绑定
RedisEventPusher 完成到那些接口,大家得以在劳动容器中那样来进行注册:

$this->app->bind('App\Contracts\EventPusher', 'App\Services\RedisEventPusher');

那就告诉了容器如若类要求1个 EventPusher 的贯彻时,那就注入二个
RedisEventPusher 的实例。将来大家得以在构造函数恐怕其他地方来写入
EventPusher 接口的档次提醒来展开保护注入:

use App\Contracts\EventPusher;

/**
 * Create a new class instance.
 *
 * @param EventPusher $pusher
 * @return void
 */
 public function __construct(EventPusher $pusher)
 {
    $this->pusher = $pusher;
 }

绑定原始类型

有时候你大概须求在类中注入许多的倚重性类,可是你恐怕也须要注入一些 PHP
的原始类型数据,比如说 integer,
boolean。你可以在上下文绑定中尤其轻松的绑定类所急需的:

$this->app->when('App\Handlers\Commands\CreateOrderHandler')
          ->needs('$maxOrderCount')
          ->give(10);

单例式绑定

singleton
方法绑定的类照旧接口只会被分析五回,也等于说随后的拜访都会回到那几个相同的实例:

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

标记

有时你可能必要分析一些相符某种类型的富有绑定。比如说,你只怕须要来建造二个告诉聚合器来收取二个暗含了不相同
Report 接口的贯彻集。在促成了 Report 的挂号之后,你可以利用 tag
方法来给它们打上标记:

$this->app->bind('SpeedReport', function () {
  //  
});

$this->app->bind('MemoryReport', function () {
  // 
});

$this->app->tag(['SpeedReport', 'MemoryReport'], 'reports');

一旦那么些服务被打上标记,你可以采用 tagged 方法来分析拿到它们:

$this->app->bind('ReportAggregator', function ($app) {
  return new ReportAggregator($app->tagged('reports'));
});

简介

laravel
提供了精锐的劳务容器工具来管理类之间的借助关系并以此来提供器重注入。倚重注入是多少个怪异的短语,其实它的意味是说所看重的类的实例通过构造函数只怕此外的点子被注入到类中。如果你要么不太知道,你可以参照作者写的这篇
《精晓依赖注入与控制反转》

让大家来看1个简短的例子:

<?php

namespace App\Jobs;

use App\User;
use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Contracts\Bus\SelfHandling;

class PurchasePodcast implements SelfHandling
{
    /**
     * The mailer implementation.
     */
     protected $mailer;

     /**
      * Create a new instance.
      *
      * @param Mailer $mailer
      * @return void
      */
      public function __construct(Mailer $mailer)
      {
        $this->mailer = $mailer;
      }

      /**
       * Purchase a podcast.
       *
       * @return void
       */
       public function handle()
       {
          //
       }
}

下边的例子中 PurchasePodcast 职责急需在播客服务被购买时发送1个email,所以大家注入了八个足以发送邮件的劳务。因为服务是流入进来的而不是类自个儿硬编码进去的,所以大家得以很简单的切换来其他发送邮件的贯彻,大家也可以很简单的去
mock,这样大家在做单元测试的时候就很不难去做一些假的数额。

可见更深层次的精晓 laravel
的劳动容器是不行需要的,它是力所能及社团强大的采纳的紧要性,服务容器构成了整整
laravel 应用的基本。

绑定

差了一点全数的劳动容器的绑定都以在服务提供者中被登记的,全体上边的例证都以在那个环境下开展出现说法的。假诺类并不曾借助什么接口,它是从未有过要求在容器中展开绑定的。容器并不须要有哪些具体的指令去什么协会那个实例,因为他俩会基于
PHP 的反光进行活动的实例化。

在劳动提供者内部,你能够通过 $this->app 来访问容器的实例。大家得以采纳
bind 方法来注册绑定,那须要传递类或接口名,然后跟上1个 Closure
闭包函数,闭包用来回到多少个所绑定类的实例:

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

留意上边的例证,大家将容器的实例作为参数传递到闭包中,那样大家就足以选择容器来分析大家所打造对象的子依赖。

上下文绑定

有时你只怕会有落到实处了同五个接口的多少个类,而且你想要在不相同的情景下流入区其他兑现,比如说,当我们的种类接受到了一个订单,大家或然想要通过
PubNub
来发送贰个轩然大波,而不是 Pusher。laravel
提供了一种简单明快的接口来定义那种作为:

$this->app->when('App\Handlers\Commands\CreateOrderHandler')
          ->needs('App\Contracts\EventPusher')
          ->give('App\Services\PubNubEventPusher');

您也可以在 give 方法中传送二个 Closure :

$this->app->when('App\Handlers\Commands\CreateOrderHandler')
          ->needs('App\Contracts\EventPusher')
          ->give(function () {
            // Resolve dependency...
          });

相关文章