依赖注入与Ioc容器

概念:

  1. 容器:可以理解为用来存放某个东西的物品(篮子?),存放的东西取决于你想往里面放点什么。在这里,我们是存放某个类,类的描述或者一个返回类实例的闭包函数。
  2. Ioc(Inversion of Control) 控制反转:可以理解为,你(用户),小红(容器)。你现在需要一把锤子,但你不想自己去造一个锤子去。你可以交给小红去处理。比如对小红说我想要一把锤子。小红会通过你给的工具名(锤子),通过自己的方法。去得到锤子的原材料(类的构造),接着在小红这里,直接造出来了一把锤子,不需要你来动手。你不需要知道这个锤子(类)所需的原材料(这里是指类的构造参数)。你通过小红(容器)而获取到了这个工具(类的实例).
  3. DI(Dependency Injection) 依赖注入:这和Ioc是同一种东西,但不同的是角度。例如:工具(锤子)依赖于小红(容器)去获取工具的原材料,并创建出工具(锤子).

特性:

  1. 减少系统之间的耦合性
  2. 增加代码稳定和健壮性
  3. 也可以理解为工厂模式的一种升级

php大神聚集地:294088839

Demo:

Class Demo1
{
public $name;
public function __construct(Demo2 $demo)
{
$this->demo = $demo;
}
public function Name()
{
$this->name = $this->demo->getName();
return $this->name;
}
}
//Demo2.php
Class Demo2
{
public function getName()
{
return "名字是xxx<br>";
}
}
//正常情况下,我们是需要先实例demo1然后在demo1的构造函数内传入demo2的
//实例,这样的耦合度太高,不宜于第二次扩展
//一般情况下的手法
//直接在new Demo1时就把Demo2给new出来并传入进去
$demo = new Demo1(new Demo2());
echo $demo->Name(); //输出名字是xxx //通过Ioc容器实现
Class Container
{
//存储当前类的实例
private static $instance;
//设置类不能直接new
private function __construct(){}
//禁止复制当前类
private function __clone(){}
//获取当前类的实例
public static function _ins()
{
//判断成员变量是否存储实例
if(empty(self::$instance))
{
//如果没有则存储并返回实例
self::$instance = new static();
return self::$instance;
}
//如果存储则直接返回
return self::$instance;
}
//成员变量register存储类的实例或类的描述
private $register = [];
//通过魔术方法__set和__get实现
//设置未定义的成员变量时,会经过__set
public function __set($key,$Cvalue)
{
//判断是否已经存储
if(array_key_exists($key,$this->register))
{
throw new Exception("错误,已存在这一的一个类");
}
$this->register[$key] = $Cvalue;
}
//访问未定义的成员变量
public function __get($key)
{
//通过build动态的去获取到类的实例
return $this->build($this->register[$key]);
}
//自动绑定,自动解析
public function build($ClassName)
{
//如果是匿名函数则直接返回执行后的结果
if ($ClassName instanceof Closure)
{
return $ClassName($this);
}
//通过反射获取到类的内部结构
$reflector = new ReflectionClass($ClassName);
//判断类能不能实例化,排除掉抽象类和接口
if(!$reflector->isInstantiable())
{
throw new Exception("对象不能实例化");
}
//获取到类的构造函数参数
$constructor = $reflector->getConstructor();
//判断构造参数是否没有定义,如果没有,则直接返回类实例
if(empty($constructor))
{
return new $ClassName();
}
//获取到构造函数内的参数
$params = $constructor->getParameters();
//递归的去调用方法解析并构造参数
$dependencies = $this->getDependencies($params);
//创建类的实例
return $reflector->newInstanceArgs($dependencies);
}
//解析参数
public function getDependencies($parameters)
{
//存储解析后的参数
$dependencies = [];
/** foreach循环获取参数,如果是变量并有默认值就直接返回默认值,如果没有 */
foreach ($parameters as $parameter) {
/** 通过反射获取到参数的类名,如果没有。。则直接返回默认值*/
$dependency = $parameter->getClass();
if (is_null($dependency)) {
// 是变量,有默认值则设置默认值
$dependencies[] = $this->resolveNonClass($parameter);
} else {
// 是一个类,递归解析
$dependencies[] = $this->build($dependency->name);
}
}
return $dependencies;
}
public function resolveNonClass($parameter)
{
// 有默认值则返回默认值
if ($parameter->isDefaultValueAvailable()) {
return $parameter->getDefaultValue();
}
//没有默认值就发出警告
throw new Exception('参数没又默认值');
}
} //通过Ioc容器获取的
//实例化容器
$app = Container::_ins();
//直接依赖注入
$app->demo1 = 'Demo1';
$demo1 = $app->demo1;
//输出名字是xxx
echo $demo1->Name();

  

参考资料:

php依赖注入与容器,Container,控制反转的更多相关文章

  1. 设计模式之————依赖注入(Dependency Injection)与控制反转(Inversion of Controller)

    参考链接: 依赖注入(DI) or 控制反转(IoC) laravel 学习笔记 —— 神奇的服务容器 PHP 依赖注入,从此不再考虑加载顺序 名词解释 IoC(Inversion of Contro ...

  2. .NET CORE学习笔记系列(2)——依赖注入【1】控制反转IOC

    原文:https://www.cnblogs.com/artech/p/net-core-di-01.html 一.流程控制的反转 IoC的全名Inverse of Control,翻译成中文就是“控 ...

  3. 基于SqlSugar的开发框架循序渐进介绍(5)-- 在服务层使用接口注入方式实现IOC控制反转

    在前面随笔,我们介绍过这个基于SqlSugar的开发框架,我们区分Interface.Modal.Service三个目录来放置不同的内容,其中Modal是SqlSugar的映射实体,Interface ...

  4. spring-第一篇之spring核心机制依赖注入(DI)/控制翻转(IoC)

    1.spring的核心机制:依赖注入(DI)/控制翻转(IoC) 什么是依赖:A对象需要调用B对象,所以A依赖于B. 什么是注入:A对象注入一个属性B对象. 什么是依赖注入(DI):A对象依赖于B对象 ...

  5. spring的容器(控制反转、依赖注入)

    一.spring的容器 ”容器“是spring的一个重要概念,其主要作用是完成创建成员变量,并完成装配. 而容器的特点”控制反转“和”依赖注入“是两个相辅相成的概念. 控制反转:我们在使用一个类型的实 ...

  6. Spring_01 spring容器、控制反转(IOC)、依赖注入(DI)

    目录 1 什么是spring框架 2 spring框架的特点 3 spring容器 3.1 什么是spring容器 3.2 spring容器创建对象的编程步骤 3.4 spring容器创建对象的方式 ...

  7. laravel服务容器(IOC控制反转,DI依赖注入),服务提供者,门脸模式

    laravel的核心思想: 服务容器: 容器:就是装东西的,laravel就是一个个的对象 放入:叫绑定 拿出:解析 使用容器的目的:这里面讲到的是IOC控制反转,主要是靠第三方来处理具体依赖关系的解 ...

  8. 自己实现一个IOC(控制翻转,DI依赖注入)容器

    1.新建一个控制台应用程序 TestIOC 2.新增一个 IocFactory类 using System; using System.Collections.Generic; using Syste ...

  9. TypeC一个微软开发的超简单.NET依赖注入/IoC容器

    控制反转(IoC,Inversion of Control)是由Martin Fowler总结出来的一种设计模式,用来减少代码间的耦合.一般而言,控制反转分为依赖注入(Dependency Injec ...

随机推荐

  1. django 登录、注册

    一.登录 1.在blogapp同级目录下新建一个userapp python manage.py startapp users 目录结构如下: 2.在主项目urls.py中新建users的includ ...

  2. docker报错Error response from daemon: driver failed programming external connectivity on endpoint *

    服务端 通常会显示 port xxx allocated的,意思就是 xxx 端口被占用了. 如果报port allocated端口占用,就docker ps 查看正使用的镜像,docker kill ...

  3. 数据采集实战:通过Python获取和分析Google趋势中Covid-19的关注程度

    在传染病研究领域,社交媒体数据已被证明可作为预测感冒和流感季节的发作和进展的指标.在本文中,我们将使用Google Trends API来衡量与冠状病毒的状态.我们将使用python谷歌趋势API p ...

  4. vue依赖注入

    大家可能知道常规组件传值,父传子使用子组件定义好的props值,子传父可以使用子组件里面定义的时间this.$emit(); 然后很多层的情况,一层一层慢慢传太慢,vue提供了依赖注入的钩子:prov ...

  5. .Net Core 实现图片验证码

    记录自己的学习,参考了网上各位大佬的技术,往往在登录的时候需要使用到验证码来进行简单的一个校验,这边使用在.net core上进行生成图片二维码 思路很简单=> 生成一个随机数->保存到服 ...

  6. 13. Java 获取指定字符串出现的次数

    方式一 /** * @param args */ public static void main(String[] args) { String srcText = "Hello World ...

  7. 拜托,别再问我什么是 B+ 树了

    前言 每当我们执行某个 SQL 发现很慢时,都会下意识地反应是否加了索引,那么大家是否有想过加了索引为啥会使数据查找更快呢,索引的底层一般又是用什么结构存储的呢,相信大家看了标题已经有答案了,没错!B ...

  8. C 2012年笔试题

    1指出程序段中的错误:分析错误的原因,并进行修改 1.1函数 swap 将两个字符串(字符数组作实参,长度不超过 100)的内容进行交换 void swap(char *pa,char *pb) { ...

  9. 【前端词典】这些功能其实不需要 JS,CSS 就能搞定

    前言 今天我们大家介绍一些你可能乍一眼以为一定需要 JavaScript 才能完成的功能,其实 CSS 就能完成,甚至更加简单. 内容已经发布在 gitHub 了,欢迎围观 Star,更多文章都在 g ...

  10. 常见排序算法总结分析之选择排序与归并排序-C#实现

    本篇文章对选择排序中的简单选择排序与堆排序,以及常用的归并排序做一个总结分析. 常见排序算法总结分析之交换排序与插入排序-C#实现是排序算法总结系列的首篇文章,包含了一些概念的介绍以及交换排序(冒泡与 ...