1. 定义一个契约(接口)

app\Contracts\SuperModuleContract.php

<?php
namespace App\Contracts; interface SuperModuleContract
{
//激活超能力,这里参数必须是array,这就是一个规范
public function activate(array $target);
}

2. 一个实现这个接口的类

app\Services\FlyPower.php

<?php
namespace App\Services; use App\Contracts\SuperModuleContract; class FlyPower implements SuperModuleContract
{
public function activate(array $target)
{
//..可以根据$target 参数进行一些操作 $ability = 'fly ability';
return $ability;
}
}

3. 创建服务提供者

app\Providers\SuperPowerProvider.php

<?php
namespace App\Providers; use Illuminate\Support\ServiceProvider;
use App\Services\FlyPower; class SuperPowerProvider extends ServiceProvider
{
public function boot()
{
//
}
public function register()
{
//singleton绑定单例
//如何使用:App::make('fly_power')方法时调用
$this->app->singleton('fly_power',function(){
return new FlyPower();
}); //bind绑定实例到接口以便依赖注入
// 如何使用:在类构造方法中实例化,并指定接口类型
$this->app->bind('App\Contracts\SuperModuleContract',function(){
return new FlyPower();
});
}
}

4. 注册服务提供者

配置文件config/app.php的providers数组中:

'providers' => [
//其他服务提供者
App\Providers\SuperPowerProvider::class,
],

5. 创建facades

app\Facades\FlyPower.php

<?php
namespace App\Facades;
use Illuminate\Support\Facades\Facade;
class FlyPower extends Facade
{
protected static function getFacadeAccessor()
{
return 'fly_power';
}
}

6. 再然后需要到配置文件config/app.php中注册门面类别名:

'aliases' => [
...//其他门面类别名映射
'FlyPower' => App\Facades\FlyPower::class,
],

7. 写一个控制器进行测试

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Contracts\SuperModuleContract;
use App;
use FlyPower; class TestController extends Controller
{ protected $superower; public function __construct(SuperModuleContract $super_power)
{
$this->super_power = $super_power;
} public function getPower(Request $request){
//实现超人的几种方式 # 使用make方式
$superman1 = App::make('fly_power')->activate(array()); # 使用facades
$superman2 = FlyPower::activate(array()); # 构造函数,类型提示,依赖注入
$superman3 = $this->super_power->activate(array()); dd($superman1, $superman2, $superman3);
} }

结果:

"fly ability"
"fly ability"
"fly ability"

证明三个超人类都实现了。

8. 进一步分析

当有超人有多种超能力的时候怎么办

8.1 定义一个获取超能力的接口

app\Contracts\GetPowerContract.php

<?php
namespace App\Contracts; interface GetPowerContract
{
public function init();
}

8.2 一个实现获取超能力接口的类

app\Services\GetPower.php

<?php
namespace App\Services; use App\Contracts\GetPowerContract;
use App; class GetPower implements GetPowerContract
{
public function init()
{
$config = config('power');
$ability = $config['ability']; $ability = App::make($ability);
return $ability;
}
}

8.3 创建配置文件

app\config\power.php

<?php

return [
'ability' => 'fly_power',
];

8.4 增加一个超能力类,需要实现超能力接口

app\Services\ShotPower.php

<?php
namespace App\Services; use App\Contracts\SuperModuleContract; class ShotPower implements SuperModuleContract
{
public function activate(array $target)
{
//..可以根据$target 参数进行一些操作 $ability = 'shot ability';
return $ability;
}
}

8.5 修改服务提供器

app\Providers\SuperPowerProvider.php

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Services\FlyPower;
use App\Services\ShotPower;
use App\Services\GetPower; class SuperPowerProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
//
} /**
* Register the application services.
*
* @return void
*/
public function register()
{
//singleton绑定单例
//如何使用:App::make('fly_power')方法时调用
$this->app->singleton('fly_power',function(){
return new FlyPower();
}); $this->app->singleton('shot_power',function(){
return new ShotPower();
}); //bind绑定实例到接口以便依赖注入
// 如何使用:在类构造方法中实例化,并指定接口类型
$this->app->bind('App\Contracts\SuperModuleContract',function(){
return new FlyPower();
}); $this->app->bind('App\Contracts\GetPowerContract',function(){
//return new FlightPower();
return new GetPower();
});
}
}

8.6 修改控制器测试代码

app\Services\ShotPower.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
//use App\Services\XPower;
use App\Contracts\SuperModuleContract;
use App\Contracts\GetPowerContract;
use App;
use FlyPower; class TestController extends Controller
{ protected $superower; //public function __construct(XPower $XPower)
//{
// $this->XPower = $XPower;
//} //public function __construct(SuperModuleContract $super_power)
//{
// $this->super_power = $super_power;
//} public function __construct(GetPowerContract $super_power)
{
$this->super_power = $super_power;
} public function getPower(Request $request){
//实现超人的几种方式
$superman1 = App::make('fly_power')->activate(array());
$superman2 = FlyPower::activate(array());
$superman3 = $this->super_power->init()->activate(array());
$superman4 = App::make('shot_power')->activate(array()); d($superman1, $superman2, $superman3, $superman4);
} }

结果

"fly ability"
"fly ability"
"fly ability"
"shot ability"

说明我们赋予的shot超能力可以正常激活

修改config/power.php内容

<?php

return [
'ability' => 'shot_power',
];

结果

"fly ability"
"fly ability"
"shot ability"
"shot ability"

第三行的更改,说明我们可以通过更改config的方式实现快速切换超人拥有的超能力

laravel5.5探究容器的秘密的更多相关文章

  1. laravel5.8 IoC 容器

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

  2. Linux中以单容器部署Nginx+ASP.NET Core

    引言 正如前文提到的,强烈推荐在生产环境中使用反向代理服务器转发请求到Kestrel Http服务器,本文将会实践将Nginx --->ASP.NET Core 部署架构容器化的过程.   Ng ...

  3. 深入理解Docker容器执行引擎runC

    1 简介 根据官方的定义:runC是一个根据OCI标准创建并运行容器的CLI tool. Docker就是基于runC创建的,简单地说,runC就是docker中最为核心的部分,容器的创建,运行,销毁 ...

  4. 老Python带你从浅入深探究List

    列表 Python中的列表(list)是最常用的数据类型之一. Python中的列表可以存储任意类型的数据,这与其他语言中的数组(array)不同. 被存入列表中的内容可称之为元素(element)或 ...

  5. 【震惊】padding-top的百分比值参考对象竟是父级元素的宽度

    引言 书写页面样式与布局是前端工程师Coding 中必不可少的一项工作,在定义页面元素的样式时,padding 属性也是经常被使用到的. padding 属性用于设置元素的内边距,其值可以是lengt ...

  6. docker-compose v3版本命令详解参考

    参考和指南 这些主题描述了Compose文件格式的第3版.这是最新的版本. Compose and Docker 兼容性矩阵 有几个版本的Compose文件格式 - 1,2,2.x和3.x.下表是快速 ...

  7. 031、none和host网络的适用场景(2019-02-18 周一)

    参考https://www.cnblogs.com/CloudMan6/p/7053617.html   本节开始,会学习docker的几种原生网络,以及如何创建自定义网络.然后探究容器之间如何通信, ...

  8. Kubernetes集群安全概述

    API的访问安全性 API Server的端口和地址 在默认情况下,API Server通过本地端口和安全端口两个不同的HTTP端口,对外提供API服务,其中本地端口是基于HTTP协议的,用于在本机( ...

  9. Linus与陈庆

    Linus 1969年末,李纳斯出生于芬兰的赫尔辛基市,算是赶上了60后的尾巴.小时候他是个其貌不扬的孩子,除了一个鼻子长的「富丽堂皇」之外乏善可陈.他为了让鼻子看上去小一些,经常戴上眼镜就不愿意摘下 ...

随机推荐

  1. python3线程介绍02(线程锁的介绍:互斥、信号、条件、时间、定时器)

    #!/usr/bin/env python# -*- coding:utf-8 -*- import threadingimport timeimport random # 1-互斥锁 Lock 同一 ...

  2. 笨办法学Python(三十五)

    习题 35: 分支和函数 你已经学会了 if 语句.函数.还有列表.现在你要练习扭转一下思维了.把下面的代码写下来,看你是否能弄懂它实现的是什么功能. from sys import exit def ...

  3. OpenGL学习 Our First OpenGL Program

    This shows you how to create the main window with the book’s application framework and how to render ...

  4. chromedp下载文件的方法,备忘一下。

    sect := `//a[@href="v/443.json"]` wd,_ := os.Getwd() fmt.Println(wd) return chromedp.Tasks ...

  5. IOS 线程的总结(及cell的图片下载)

    零.线程的注意点(掌握) 1.不要同时开太多的线程(1~3条线程即可,不要超过5条)2.线程概念1> 主线程 : UI线程,显示.刷新UI界面,处理UI控件的事件2> 子线程 : 后台线程 ...

  6. hdu-3449 Consumer---有依赖性质的背包

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3449 题目大意: fj打算去买一些东西,在那之前,他需要一些盒子去装他打算要买的不同的物品.每一个盒 ...

  7. Xamarin.Forms随手记

    1. 更新Android SDK要从VS的工具栏上SDK Manager那里更新,不要像我一样之前搞了好几份SDK放在不同的地方,结果把自己搞糊涂了,更新了半天(真的是花了半天时间)才发现更新的地方不 ...

  8. c#方法(整理自菜鸟网)

    定义一个方法,根本上说就是在声明它的结构的元素 定义方法的语法如下: <访问修饰符(public啥的)> < 返回值数据类型,没有返回值的为void >  <方法名称&g ...

  9. 关于 npm install 命令

    使用 `npm install` 命令安装模块时 ,有以下几种形式: 安装模块到项目 node_modules 目录下,不会将模块依赖写入 dependencies 或 devDependencies ...

  10. mac home brew install go

    mac利器home brew安装Go 首先你得需要安装home brew和ruby环境(因为home brew依赖ruby) 如果没有请自行到链接安装 准备好之后就开始安装go了 brew updat ...