依赖注入与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. js中排序方法

    有些代码一两个月都会忘了,有空多做下总结,记录下来,等需要用到的时候可以来翻翻总结的博客.写技术博客,对自己是一种总结,对别人,是一种参考. 1.sort()方法 var ar1=[2,4,6,8,1 ...

  2. C#桌面开发的未来WebWindow

    目录 WebWindow 源码 作者博客 基于Chromium的Edge 体验 体验方式一: 体验方式二: 遗留的问题 WebWindow WebWindow是跨平台的库. Web Window的当前 ...

  3. Java中将文件夹复制到另一个文件夹

    文件夹的拷贝*** public static void copyDir(String sourcePath, String newPath) { File start = new File(sour ...

  4. spring多数据源分布式事务的分析与解决方案

    一.概述 1.业务背景 对老系统进行重构合并,导致新系统需要同时对3个数据库进行管理.由于出现跨库业务,需要实现分布式事务. 2.开发环境 spring框架版本  4.3.10.RELEASE 持久层 ...

  5. Linux与unix shell编程指南

    第14章 环境和shell变量 1.使用变量时,尽量用花括号将之括起来,防止shell误解变量值. 2.设置变量时的不同模式 variable-name=value 设置实际值到variable-na ...

  6. (转)解决windows live writer的段首缩进问题

    原文地址:http://blog.csdn.net/xiao_wanpeng/article/details/6381799 Windows live writer 默认是没有段首缩进的,并且不能修改 ...

  7. Natas5 Writeup(Cookie伪造)

    Natas5: 提示不允许进入,没有登录,burp抓包,查看cookie信息后发现存在loggedin项,且值为0,猜测该值代表是否登录,将其修改为1,得到flag. flag:aGoY4q2Dc6M ...

  8. Fast and accurate bacterial species identification in urine specimens using LC-MS/MS mass spectrometry and machine learning (解读人:闫克强)

    文献名:Fast and accurate bacterial species identification in urine specimens using LC-MS/MS mass spectr ...

  9. VMware Tools失效的处理方案

    VMware Tools是一个实现主机与虚拟机文件分享,具有可支持自由拖拽的功能的工具,如果没有VM tools,那么没有了复制粘贴切换的虚拟机是很不方便的. 长时间未开的虚拟机,一次尝试拖拽Wind ...

  10. Python-hashlib、OS、Random、sys、zipfile模块

    # print(sys.version) #python 版本 # print(sys.path) # print(sys.platform) #当前什么系统 # print(sys.argv) #当 ...