依赖注入(Dependency Injection,DI)容器就是一个对象,它知道怎样初始化并配置对象及其依赖的所有对象。

所谓的依赖就是,一个对象,要使用另外一个对象才能完成某些功能。那么这个对象就依赖于被使用的对象。

例如:

/**
* 厨师
*/
class cook {
/**
* 制作食物
*/
public function cooking() {
$food = new food();
echo $food->get(),"汤<br/>";
}
}
/**
* 食材
*/
class food{
/**
* 提供食材
*/
public function get() {
return '西红柿鸡蛋';
}
}

厨师类 在 制作食物 的时候需要用到 食材类 提供食材,才能完成食物的制作。

所以厨师类依赖于食材类。

但是这种直接在类内部实例化一个对象的方式来得到对象,是一种强耦合的做法。

应该把食材的提供者(数据结构)与食物的制作方法(算法)进行分离。

再改动一下代码:

/**
* 厨师
*/
class cook {
private $food;
public function __construct(food $food) {
$this->food = $food;
}
/**
* 制作食物
*/
public function cooking() {
echo $this->food->get(),"汤<br/>";
}
}
/**
* 食材
*/
class food{
/**
* 提供食材
*/
public function get() {
return '西红柿鸡蛋';
}
}

改动之后的代码是在实例化一个厨师的时候就把食材类传递进去。

但是这个时候,如果改动了,food类,那么极有可能导致cook类不能得到食材。这个时候它们之间还是强耦合在一块。

况且厨师不可能总是做西红柿鸡蛋汤啊,他需要其它食材。

再改动一下代码:

/**
* 厨师
*/
class cook {
private $food;
public function __construct(food $food) {
$this->food = $food;
}
/**
* 制作食物
*/
public function cooking() {
echo $this->food->get(),"汤<br/>";
}
}
/**
* 食材接口
*/
interface food{
public function get();
}
/**
* 海鲜类食材
*/
class seafood implements food{
/**
* 提供食材
*/
public function get() {
return '鲜鱼';
}
}
/**
* 家禽类食材
*/
class fowlfood implements food{
/**
* 提供食材
*/
public function get() {
return '西红柿鸡蛋';
}
}

把 食材提供 用一个接口进行约定,然后各类食材都必须实现那个接口。

通过接口,把 cook 与 food 彻底分开。

这样我们的客户端代码就是:

$cook = new cook(new seafood);
$cook->cooking();
$cook = new cook(new fowlfood);
$cook->cooking();

这样在每次使用$cook对象的时候,都需要new一下 实现了food接口的类。

那么对于这种依赖的关系,如果能够让一个对象专门来处理,而不是手工去new一下food类。那么这种处理过程就叫依赖注入。

这个处理依赖关系的对象就是Yii框架中的叫“”容器”的对象。

下面是Yii中依赖注入容器的使用:

<?php
namespace app\controllers;
use yii\web\Controller;
use \YII; class TestController extends Controller
{
public function actionIndex() {
//实例化依赖注入容器
$container = new \yii\di\Container;
//设置food接口与具体的实现类之间的关系
$container->set('app\controllers\food','app\controllers\fowlfood');
//$container->set('app\controllers\food','app\controllers\seafood');
//通过依赖注入容器得到厨师对象
$cook = $container->get('app\controllers\cook');
$cook->cooking();
}
} /**
* 厨师
*/
class cook {
private $food;
public function __construct(food $food) {
$this->food = $food;
}
/**
* 制作食物
*/
public function cooking() {
echo $this->food->get(),"汤<br/>";
}
}
/**
* 食材接口
*/
interface food{
public function get();
}
/**
* 海鲜类食材
*/
class seafood implements food{
/**
* 提供食材
*/
public function get() {
return '鲜鱼';
}
}
/**
* 家禽类食材
*/
class fowlfood implements food{
/**
* 提供食材
*/
public function get() {
return '西红柿鸡蛋';
}
}

YII框架的依赖注入容器的更多相关文章

  1. YII框架的依赖注入容器与服务定位器简述

    依赖注入容器 依赖注入(Dependency Injection,DI)容器就是一个对象use yii\di\Container,它知道怎样初始化并配置对象及其依赖的所有对象. 依赖注入和服务定位器都 ...

  2. yii依赖注入和依赖注入容器

    依赖注入和依赖注入容器¶ 为了降低代码耦合程度,提高项目的可维护性,Yii采用多许多当下最流行又相对成熟的设计模式,包括了依赖注入(Denpdency Injection, DI)和服务定位器(Ser ...

  3. [ASP.NET Core 3框架揭秘] 依赖注入[5]: 利用容器提供服务

    毫不夸张地说,整个ASP.NET Core框架是建立在依赖注入框架之上的.ASP.NET Core应用在启动时构建管道以及利用该管道处理每个请求过程中使用到的服务对象均来源于依赖注入容器.该依赖注入容 ...

  4. Yii2.0 依赖注入(DI)和依赖注入容器的原理

    依赖注入和依赖注入容器 为了降低代码耦合程度,提高项目的可维护性,Yii采用多许多当下最流行又相对成熟的设计模式,包括了依赖注入(Denpdency Injection, DI)和服务定位器(Serv ...

  5. yii2之依赖注入与依赖注入容器

    一.为什么需要依赖注入 首先我们先不管什么是依赖注入,先来分析一下没有使用依赖注入会有什么样的结果.假设我们有一个gmail邮件服务类GMail,然后有另一个类User,User类需要使用发邮件的功能 ...

  6. webapi框架搭建-依赖注入之autofac

    前言 c#的依赖注入框架有unity.autofac,两个博主都用过,感觉unity比较简单而autofac的功能相对更丰富(自然也更复杂一点),本篇将基于前几篇已经创建好的webapi项目,引入au ...

  7. IoC 依赖注入容器 Unity

    原文:IoC 依赖注入容器 Unity IoC 是什么? 在软件工程领域,“控制反转(Inversion of Control,缩写为IoC)”是一种编程技术,表述在面向对象编程中,可描述为在编译时静 ...

  8. [ASP.NET Core 3框架揭秘] 依赖注入:控制反转

    ASP.NET Core框架建立在一些核心的基础框架之上,这些基础框架包括依赖注入.文件系统.配置选项和诊断日志等.这些框架不仅仅是支撑ASP.NET Core框架的基础,我们在进行应用开发的时候同样 ...

  9. [ASP.NET Core 3框架揭秘] 依赖注入[8]:服务实例的生命周期

    生命周期决定了IServiceProvider对象采用怎样的方式提供和释放服务实例.虽然不同版本的依赖注入框架针对服务实例的生命周期管理采用了不同的实现,但总的来说原理还是类似的.在我们提供的依赖注入 ...

随机推荐

  1. 5_PHP数组_3_数组处理函数及其应用_9_数组集合运算函数

    以下为学习孔祥盛主编的<PHP编程基础与实例教程>(第二版)所做的笔记. 数组集合运算函数 1. array_merge() 函数 程序: <?php $array1 = array ...

  2. springboot实现读写分离(基于Mybatis,mysql)

    近日工作任务较轻,有空学习学习技术,遂来研究如果实现读写分离.这里用博客记录下过程,一方面可备日后查看,同时也能分享给大家(网上的资料真的大都是抄来抄去,,还不带格式的,看的真心难受). 完整代码:h ...

  3. React Native 开发豆瓣评分(五)屏幕适配方案

    前言 React Native 是以实际像素 dp 为单位的,这导致在不同分辨率的屏幕会有不一样的显示情况. 在原生 Android 中,可以根据不同的分辨率添加不同的样式目录,以解决不同分辨率的问题 ...

  4. Imagetragick RCE(CVE-2016–3714)复现

    CVE-2016–3714: 闲着没事突然想起这个洞来,借用vulhub复现一下 poc有很多:https://github.com/ImageTragick/PoCs 我用的 push graphi ...

  5. FreeRTOS计数型信号量

    API函数 //创建 #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) #define xSemaphoreCreateCounting( uxMaxCount ...

  6. SAP官网发布的react教程

    大家学习React的时候,用的是什么教程呢?Jerry当时用的阮一峰博客上的入门教程,因为React使用的JSX语法并不是所有的浏览器都支持,所以还得使用browser.js在浏览器端将JSX转换成J ...

  7. CDN详解

    一.定义 背景: 当下的互联网应用都包含大量的静态内容,但静态内容以及一些准动态内容又是最耗费带宽的,特别是针对全国甚至全世界的大型网站,如果这些请求都指向主站的服务器的话,不仅是主站服务器受不了,单 ...

  8. mysql8.x 新版本jdbc连接方式

    旧版本,MySQL Connector/J 5.x 版本的连接方式:url = jdbc:mysql://localhost:3306/thrcloud_db01?useUnicode=true&am ...

  9. 使用protobuf (proto3, C++和go语言)

    在这里,我先讲述C++使用protobuf,之后,会补充使用go语言使用protobuf. 使用protobuf需要有如下步骤: 在.proto文件中定义消息(message)格式. 使用protob ...

  10. 解决通过vue-router打开tab页,下次进入还是上次history缓存的界面状态的问题

    一.问题描述: 1. 跳转模式:界面A-->界面B(界面A中通过 this.$router.push({name:'组件B名称', params: {参数}}) 通过打开新tab页的方式打开界面 ...