依赖注入与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. openwrt 为软件包添加服务

    手动修改 rc.local 加入也可以实现自启动,缺点手动修改太麻烦,停止只能用 kill . 配置成服务最方便了,可以启用或禁用,启动,停止,重启非常方便. 在openwrt 中使用服务 servi ...

  2. Falsk 路由简析

    添加路由 我们熟知添加路由的方式是装饰器: @app.route('/') def hello_world(): return 'Hello World!' #访问web得到 'Hello World ...

  3. unittest测试框架详解

    单元测试的定义 1. 什么是单元测试? ​ 单元测试是指,对软件中的最小可测试单元在与程序其他部分相隔离的情况下进行检查和验证的工作,这里的最小可测试单元通常是指函数或者类,一般是开发来做的,按照测试 ...

  4. mysql中实现更新数据+1,再次更新数据-1

    $sql="update article set comment=comment^1 where a_id=2"; 这条语句你会发现当你更新comment字段时为1,再次更新时为0 ...

  5. JAVAEE学习day02

    1.数据类型的转换 1>自动转换(隐式) // 将取值范围小的数据类型自动提升为取值范围大的类型 // 定义byte类型数据 byte b = 10; // 定义short类型数据 short ...

  6. C++ 指针实现字符串倒序排列

    #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <coni ...

  7. SIP压力测试——奇林软件kylinPET

    一.Sip协议简介: SIP(Session Initiation Protocol,会话初始协议)是由IETF(Internet Engineering Task Force,因特网工程任务组)制定 ...

  8. 读书笔记——吴翰清《白帽子讲Web安全》

    目录 第一篇 世界观安全 一 我的安全世界观 第二篇 客户端脚本安全 一 浏览器安全二 跨站脚本攻击(XSS)三 跨站点请求伪造(CSRF)四 点击劫持(ClickJacking)五 HTML5 安全 ...

  9. 微商贴吧企业新浪微博怎么找客户_怎么做好seo

    写的几篇文章对于seo的引流量方面的 怎么做好网络seo优化之SEO项目团队组建 品牌营销_中小企业网络推广的办法 微商怎么引流客源?微商没有客户的解决办法?下 微商怎么引流客源?微商没有客户的解决办 ...

  10. Thinkphp绕过宝塔getshell

    可以看到直接被拦了,经测试这里是敏感函数字符拦截,大部分有用的敏感函数都被拦了,这里面被拦的是phpinfo() Emmmm,怎么办呢..... 直接执行代码不行,那么就写入代码吧,用file_put ...