容器主要是为了实现控制反转,控制反转的最终目的是减少类的耦合

1. 比较典型的例子就是 cache 缓存

# 不反转的例子 Cache类依赖Redis, 每次使用缓存的时候我们都要new Redis()
class Cache {
public function __construct()
{
$this->store = new Redis();
}
} # 反转使用容器, 由容器实例化对应的类,把控制权给了容器, 每个使用缓存的地方, 引入的都是容器, 使用make解析出 缓存对象
class Cache {
public function __construct(Container $container)
{
$this->$container = $container; $this->store = $this->container->make('cache');
}
}

容器如何解析出redis缓存呢

# 类似这样,绑定一个redis对象,使用的时候直接make()解析即可
$this->app->singleton('cache', function ($app) {
return new Redis($app);
});

试想: 如果我们有一天不想用redis缓存了,不使用反转的时候,我们是不是不需要去每个使用缓存的类中修改,使用反转的话是不是只需要在绑定的时候修改即可,当然实际的应用中,我们也不必去修改绑定,我们可以类似的通过配置来实现快速切换。

# CacheManager类中你可以通过读取配置getConfig()等等来控制你想要的逻辑
$this->app->singleton('cache', function ($app) {
return new CacheManager($app);
});

2. 容器顾名思义,其实就是完成存取过程

  • 先往容器里绑定东西---绑定过程
  • 再向容器拿绑定过的东西---解析过程

2.1 绑定过程

我们都可以绑定什么呢,官方给出了4种绑定

简单绑定

传递我们想要注册的类或接口名称再返回类的实例的 Closure :

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

绑定单例

singleton 方法将类或接口绑定到只能解析一次的容器中。绑定的单例被解析后,相同的对象实例会在随后的调用中返回到容器中:

$this->app->singleton('HelpSpot\API', function ($app) {
return new HelpSpot\API($app->make('HttpClient'));
});

绑定实例

你也可以使用 instance 方法将现有对象实例绑定到容器中。给定的实例会始终在随后的调用中返回到容器中

$api = new HelpSpot\API(new HttpClient);

$this->app->instance('HelpSpot\API', $api);

绑定初始数据

当你有一个类不仅需要接受一个注入类,还需要注入一个基本值(比如整数)。你可以使用上下文绑定来轻松注入你的类需要的任何值:

$this->app->when('App\Http\Controllers\UserController')
->needs('$variableName')
->give($value);

2.2 解析过程

laravel使用resolve方法来进行解析, 核心的思路:

  1. 首先判断instances中是否有abstract, 有的话,直接返回。没有接着往下看。

  2. 其次,判断bindings里面有没有abstract,有的话拿到注册的匿名函数, 并执行匿名函数。

  3. 前两步都没有找到的话,那laravel会把abstract当作一个类名,然后通过反射 构建这个类名的实例化对象。所以不需要事先绑定一个类, 通过Make函数可以直接实例化类 当然需要可自动加载这个类。试想我们是不是可以通过App::make()方法来实例化一个类。

laravel提供了make方法实现resolve过程

    # 注意 make 是不能传递参数的

    public function make($abstract)
{
return $this->resolve($abstract);
}

如果每次都去make是不是很麻烦,于是laravel实现了arrayAccess的机制。

比如上面例子绑定的cache,我们可以这样取

$store = $this->app['cache']

app('cache')

更进一步,laravel还有aliases

通过config/app.php中的aliases数组,找到facades类,继而找到容器中的绑定项

    'aliases' => [
'Cache' => Illuminate\Support\Facades\Cache::class,
// ...其他配置
],
``` 实际上还有一种通过自动注入 你可以简单地使用「类型提示」的方式在由容器解析的类的构造函数中添加依赖项,包括 控制器、事件监听器、队列任务、中间件 等。 事实上,这是你的大多数对象也应该由容器解析。 ```
<?php namespace App\Orders; use Illuminate\Contracts\Cache\Repository as Cache; class Repository
{
protected $cache; public function __construct(Cache $cache)
{
$this->cache = $cache;
}
}
```

laravel5.5容器的更多相关文章

  1. 9.Laravel5学习笔记:在laravel中注冊自己的服务到容器中

    问题描写叙述 或许标题写的不够清楚.实际情况是,在我使用laravel的过程中.须要将自己的一个类,通过服务提供者注冊到IOC容器中,可是在实际操作过程中.出现了下面错误: Unresolvable ...

  2. Docker容器里配置计划任务 crontab(DaoCloud+Docker +Laravel5)

    最近项目涉及到一个定时任务的功能,所以去这几天研究了一下 crontab 的使用方法,按照网上的相关教程顺利在自己的电脑上成功开启了这个功能 Laravel + crontab 添加 crontab ...

  3. laravel5.2总结--服务容器(依赖注入,控制反转)

    1.依赖 我们定义两个类:class Supperman 和 class Power,现在我们要使用Supperman ,而Supperman 依赖了Power class Supperman { p ...

  4. Laravel5.1学习笔记12 系统架构4 服务容器

    Service Container 介绍 绑定的用法  绑定实例到接口 上下文绑定 标签 解析 容器事件 #介绍 The Laravel service container is a powerful ...

  5. laravel5.8 IoC 容器

    网上 对容器的解释有很多,这里只是记录,搬运! 1.简单理解: 2019-10-10 11:24:09 解析 lavarel 容器 IoC 容器 作用 就是 “解耦” .“依赖注入(DI) IoC 容 ...

  6. laravel5.5的服务容器分析

    简介 服务容器是Laravel的核心.见名知意,服务容器就是一个存放服务的地方,当我们需要某个服务的时候,我们就可以从这个容器中取出我们需要的服务.用更专业一点的术语来说,官网定义服务容器是这样的: ...

  7. laravel5.5探究容器的秘密

    目录 1. 定义一个契约(接口) 2. 一个实现这个接口的类 3. 创建服务提供者 4. 注册服务提供者 5. 创建facades 6. 再然后需要到配置文件config/app.php中注册门面类别 ...

  8. Laravel5 快速认证逻辑流程分析

    Laravel5本身自带一套用户认证功能,只需在新项目下,使用命令行php artisan make:auth 和 php artisan migrate就可以使用自带的快速认证功能. 以下为分析登录 ...

  9. Laravel 服务容器、服务提供器、契约实例讲解

        前言 刚开始看laravel服务容器.契约.服务提供器的确生涩难懂,不单单是概念繁多,而且实际的demo很难找(找是找到了,但难用啊),最后就隔一段时间看一遍,大概个十来遍,还真给看出个门道, ...

随机推荐

  1. [转]Android时间获取与使用

    编写Android网络程序时难免会遇到手机时间不准确的问题,本文总结了一些常用的时间获取与校正方法: 转载请注明:http://blog.csdn.net/xzy2046 1.获取本机当前时间: Ti ...

  2. SAP成都研究院Sunshine: 我的C4C实习感受和保研之路

    今天的文章来自SAP成都一位实习生,曾经和Jerry同在C4C成都开发团队一起工作过.在Sunshine最后一个工作日里,Jerry和Sunshine一起吃饭的时候,她曾经聊到接下来的保研打算和将来工 ...

  3. Android(java)学习笔记63:Clock App 编写报错01

    1. 首先我们二话不说直接先看报错内容如下: 07-12 08:25:03.572: E/dalvikvm(3602): native fork pid:0 done. 07-12 08:25:03. ...

  4. 目的檔格式 (ELF)

    http://ccckmit.wikidot.com/lk:elf 目的檔ELF 格式(Executable and Linking Format) 是 UNIX/Linux 系統中較先進的目的檔格式 ...

  5. 谷歌Web中文开发手冊:3响应式

    https://developers.google.com/web/fundamentals/getting-started/your-first-multi-screen-site/responsi ...

  6. Uva 11078 简单dp

    题目链接:http://uva.onlinejudge.org/external/110/11078.pdf a[i] - a[j] 的最大值. 这个题目马毅问了我,O(n^2)超时,记忆化一下当前最 ...

  7. 课程设计__C++初步,C++对C的扩充

    小草的C++要结课了,小草终于翻起书来,小草用的老谭的书,有什么不对的就找老谭去吧. ///C++初步 ///C++对C的扩展 #include <iostream> using name ...

  8. cutil.h问题

    CUDA5.0没有cutil.h头文件,貌似用helper_cuda.h文件代替,暂时没出问题.

  9. C编程经验总结4

    {}体里的语句不管在一行还是在多行,之间都是要有: for与for之间可以是独立的,也可以是相互嵌套的 For( ; i<5; )=for( ;i<=4;  ) 一般都是在循环里面进行判断 ...

  10. 统计寄存器AX中1 的个数

    ;==================================== ; 统计寄存器AX中1 的个数 DATAS segment DATAS ends CODES segment START: ...