专栏首页网管叨bi叨Laravel神奇的服务容器

Laravel神奇的服务容器

Laravel的核心是IocContainer, 文档中称其为“服务容器”,服务容器是一个用于管理类依赖和执行依赖注入的强大工具,Laravel中的功能模块比如 Route、Eloquent ORM、Request、Response等等等等,实际上都是与核心无关的类模块提供的,这些类从注册到实例化,最终被我们所使用,其实都是 laravel 的服务容器负责的。

服务容器中有两个概念控制反转(IOC)和依赖注入(DI):

依赖注入和控制反转是对同一件事情的不同描述,它们描述的角度不同。依赖注入是从应用程序的角度在描述,应用程序依赖容器创建并注入它所需要的外部资源。而控制反转是从容器的角度在描述,容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源。

在Laravel中框架把自带的各种服务绑定到服务容器,我们也可以绑定自定义服务到容器。当应用程序需要使用某一个服务时,服务容器会讲服务解析出来同时自动解决服务之间的依赖然后交给应用程序使用。

本篇就来探讨一下Laravel中的服务绑定和解析是如何实现的

服务绑定

常用的绑定服务到容器的方法有instance, bind, singleton, alias。下面我们分别来看一下。

instance

将一个已存在的对象绑定到服务容器里,随后通过名称解析该服务时,容器将总返回这个绑定的实例。

$api = new HelpSpot\API(new HttpClient);
$this->app->instance('HelpSpot\Api', $api);

会把对象注册到服务容器的$instances属性里

[
    'HelpSpot\Api' => $api//$api是API类的对象,这里简写了
]

bind

绑定服务到服务容器

有三种绑定方式:

1.绑定自身
$this->app->bind('HelpSpot\API', null);

2.绑定闭包
$this->app->bind('HelpSpot\API', function () {
   return new HelpSpot\API();
});//闭包直接提供类实现方式
$this->app->bind('HelpSpot\API', function ($app) {
   return new HelpSpot\API($app->make('HttpClient'));
});//闭包返回需要依赖注入的类
3. 绑定接口和实现
$this->app->bind('Illuminate\Tests\Container\IContainerContractStub', 'Illuminate\Tests\Container\ContainerImplementationStub');

bind把服务注册到服务容器的$bindings属性里类似这样:

$bindings = [
   'HelpSpot\API' =>  [//闭包绑定
      'concrete' => function ($app, $paramters = []) {
         return $app->build('HelpSpot\API');
      },
      'shared' => false//如果是singleton绑定,这个值为true
   ]    
   'Illuminate\Tests\Container\IContainerContractStub' => [//接口实现绑定
      'concrete' => 'Illuminate\Tests\Container\ContainerImplementationStub',
      'shared' => false
   ]
]

singleton

public function singleton($abstract, $concrete = null)
{
   $this->bind($abstract, $concrete, true);
}

singleton 方法是bind方法的变种,绑定一个只需要解析一次的类或接口到容器,然后接下来对于容器的调用该服务将会返回同一个实例

alias

把服务和服务别名注册到容器:

public function alias($abstract, $alias)
{
   $this->aliases[$alias] = $this->normalize($abstract);
}

alias 方法在上面讲bind方法里有用到过,它会把把服务别名和服务类的对应关系注册到服务容器的$aliases属性里。例如: $this->app->alias('\Illuminate\ServiceName', 'service_alias'); 绑定完服务后在使用时就可以通过 $this->app->make('service_alias'); 将服务对象解析出来,这样make的时候就不用写那些比较长的类名称了,对make方法的使用体验上有很大提升。

服务解析

服务解析是从服务容器中解析出在服务绑定过程中注册到服务容器里的对象,我们能过很方便的通过make方法来解析出服务对象,通过如果服务对象如果有依赖其他类对象的话服务容器也会帮助我们依次解决依赖从而免去了在程序里使用服务对象前先要在代码里实力化一堆依赖对象的繁重操作。 你可以点击“阅读原文”查看Laravel服务容器详细的源码解析,希望看完后能解决你在使用过程中的一些疑惑。

本文分享自微信公众号 - 网管叨bi叨(kevin_tech),作者:网管

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-12-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Laravel服务提供器

    服务提供器是所有 Laravel 应用程序引导中心。你的应用程序自定义的服务、第三方资源包提供的服务以及 Laravel 的所有核心服务都是通过服务提供器进行注...

    KevinYan
  • 原子操作和互斥锁的区别

    这个系列的文章里介绍了很多并发编程里经常用到的技术,除了Context、计时器、互斥锁还有通道外还有一种技术--原子操作在一些同步算法中会被用到。今天的文章里我...

    KevinYan
  • 完善你的Laravel异常处理

    异常处理是编程中十分重要但也最容易被人忽视的语言特性,它为开发者提供了处理程序运行时错误的机制,对于程序设计来说正确的异常处理能够防止泄露程序自身细节给用户,给...

    KevinYan
  • 从Q3财报看李彦宏的技术范儿

    美孚石油创办人约翰·洛克菲勒著有一书,《只有偏执狂才能成功》。此话看上去稍显绝对,但事实上偏执确实是许多成功人士共有的特质。现在,李彦宏在O2O这件事情上就显得...

    罗超频道
  • 《最强大脑》人机大战最大价值:小度们从此走到各行各业中去

    在Master全胜人类围棋选手之后,另一场人机大战正在进入尾声:百度小度机器人已在《最强大脑》完成三期挑战,分别取得3:2、1:1、2:0的成绩,两胜一平,直接...

    罗超频道
  • Hexo博客之butterfly主题优雅魔改系列(持续更新)

    相信在这之前,大家肯定看过网上的各种魔改教程。但是这些魔改教程基本上千篇一律,都是一种方式,大量修改模板(主题源文件)。这种方式的好处就是简单快速且直接,缺点就...

    Dreamy.TZK
  • 【Web技术】421- 富文本原理介绍

    最近产品想让我在富文本里加个旋转图片的功能,我一想?,就觉得事情并不简单,因为印象中好像没见过这种操作。果然,经过一番百度之后,确实没怎么看到相关信息,这也就意...

    pingan8787
  • Spring中的切面

    我们在使用增强时知道,横切逻辑会添加到目标类的所有方法中,无论是方法前还是方法后。而有时,我们只想将增强添加到我们需要添加的方法中,例如添加事物管理的增强。这时...

    吉林乌拉
  • Flutter插件开发之APK自动安装

    Flutter Plugin是一种特殊的包,包含一个用Dart编写的API定义,结合Android和iOS的平台特定实现,从而达到二者兼容。1、应用的Flutt...

    CCCruch
  • 【富文本】268- 富文本原理了解一下?

    最近产品想让我在富文本里加个旋转图片的功能,我一想?,就觉得事情并不简单,因为印象中好像没见过这种操作。果然,经过一番百度之后,确实没怎么看到相关信息,这也就意...

    pingan8787

扫码关注云+社区

领取腾讯云代金券