lumen-ioc容器测试 (6)
问题四、我们现在遇到的问题是构建对象的时候需要明确构造函数的参数类型、数量。并且增加程序的透明度
# class Container# 复制上面的代码
class Person{
private $name;
public function __construct($param) {
$this->name = $param['name'] ?? 'unknown';
} public function getName() {
return $this->name;
}
}
我们上一个版本的解决方案显然不是很理想。我们不能要求每个类的构造函数都传一个$param
数组,这样不透明也不现实
那么如果我们要这样使用一个容器呢?
class Person{
private $name;
private $isProgrammer;
public function __construct($name,$isProgrammer = true) {
$this->name = $name;
$this->isProgrammer = $isProgrammer;
} public function me() {
$message = $this->isProgrammer ? ',Ta是一个程序员' :'';
return "姓名: {$this->name} $message";
}
}
$container = new Container();
$container->bind('Person');
$p1 = $container->make('Person',[
'name' => 'lilei',
]); echo $p1->me();
接下来我们来解决上述问题
class Container { private $bindings = [];
private $instances = []; public function getClosure($concrete) {
return function($parameter = []) use($concrete) {
# 在这里我们找到了判断初始化函数的契机,利用反射我们可以做很多事,包括我们的问题
# 1.获得一个$concrete类反射
$reflector = new ReflectionClass($concrete);
# 2.判断这个类能否被实例化,例如 private function __construct(){}
if(!$reflector->isInstantiable()) {
throw new Exception("{$concrete} 无法被实例化");
} # 3.获取构造函数反射方法
$constructor = $reflector->getConstructor(); # 4.获取参数列表
$parameters = $constructor->getParameters(); # 5.遍历参数列表
$instances = [];
foreach ($parameters as $_parameter) {
# 如果已经$parameter中已经设置了对应的参数
if(isset($parameter[$_parameter->name])) {
$instances[] = $parameter[$_parameter->name];
continue;
}
# 如果没设置判断一下这个参数是否存在默认值
if(!$_parameter->isDefaultValueAvailable()) {
throw new Exception("{$concrete} 无法被实例化,缺少参数{$_parameter->name}");
} $instances[] = $_parameter->getDefaultValue();
} # 这里就需要通过反射来构建对象了
// return new $concrete($parameter);
return $reflector->newInstanceArgs($instances);
};
} public function bind($abstract , $concrete=null, $shared = false)
{
if (is_null($concrete)) {
$concrete = $abstract;
} if (!$concrete instanceof Closure) {
$concrete = $this->getClosure($concrete);
} $this->bindings[$abstract] = [
'concrete' => $concrete,
'shared' => $shared
];
} public function make($abstract ,array $parameters = []) {
if (!isset($this->bindings[$abstract])) {
return false;
} if (isset($this->instances[$abstract])) {
return $this->instances[$abstract];
} # 先获取到具体的类型
$concrete = $this->bindings[$abstract]['concrete'];
# 这里需要思考一下
# 到目前为止我们的$this->bindings[$abstract]['concrete']里存储的都是通过getClosure方法生成的闭包。
# 那么直接在这里判断类型肯定行不通,所以我们跳到getClosure里面去看看
$object = $concrete($parameters);
if($this->bindings[$abstract]['shared']) {
$this->instances[$abstract] = $object;
} return $object;
}
} class Person{
private $name;
private $isProgrammer;
public function __construct($name,$isProgrammer = true) {
$this->name = $name;
$this->isProgrammer = $isProgrammer;
} public function me() {
$message = $this->isProgrammer ? ',Ta是一个程序员' :'';
return "姓名: {$this->name} $message";
}
}
$container = new Container();
$container->bind('Person');
$p1 = $container->make('Person',[
'name' => 'lilei',
]); echo $p1->me();
lumen-ioc容器测试 (6)的更多相关文章
- lumen-ioc容器测试 (1)
lumen-ioc容器测试 (1) lumen-ioc容器测试 (2) lumen-ioc容器测试 (3) lumen-ioc容器测试 (4) lumen-ioc容器测试 (5) lumen-ioc容 ...
- 自定义模拟一个Spring IOC容器
一.模拟一个IOC容器: 介绍:现在,我们准备使用一个java project来模拟一个spring的IOC容器创建对象的方法,也就是不使用spring的jar自动帮助我们创建对象,而是通过自己手动书 ...
- Aoite 系列(02) - 超动感的 Ioc 容器
Aoite 系列(02) - 超动感的 Ioc 容器 Aoite 是一个适于任何 .Net Framework 4.0+ 项目的快速开发整体解决方案.Aoite.Ioc 是一套解决依赖的最佳实践. 说 ...
- AutoFac使用~IOC容器(DIP,IOC,DI)
#cnblogs_post_body h1 { background-color: #A5A5A5; color: white; padding: 5px } Autofac一款IOC容器,据说比Sp ...
- IOC容器特性注入第一篇:程序集反射查找
学习kooboo的框架发现它的注入容器方法比较特别,同样是利用MVC的注入点,但它是查找网站下面bin所有的DLL利用反射查找特性找到对应的服务注入到容器. 这样的好处很简单:完全可以不用关心IOC容 ...
- 对依赖倒置原则(DIP)及Ioc、DI、Ioc容器的一些理解
1.概述 所谓依赖倒置原则(Dependence Inversion Principle)就是要依赖于抽象,不要依赖于具体.简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模 ...
- IOC容器中bean的生命周期
一.Bean的生命周期 Spring IOC容器可以管理Bean的生命周期,允许在Bean生命周期的特定点执行定制的任务. Spring IOC容器对Bean的生命周期进行管理的过程如下: (1).通 ...
- IoC容器Autofac - Autofac + Asp.net MVC + EF Code First(转载)
转载地址:http://www.cnblogs.com/JustRun1983/archive/2013/03/28/2981645.html 有修改 Autofac通过Controller默认构造 ...
- TypeC一个微软开发的超简单.NET依赖注入/IoC容器
控制反转(IoC,Inversion of Control)是由Martin Fowler总结出来的一种设计模式,用来减少代码间的耦合.一般而言,控制反转分为依赖注入(Dependency Injec ...
- IoC 之 2.2 IoC 容器基本原理(贰)
2.2.1 IoC容器的概念 IoC容器就是具有依赖注入功能的容器,IoC容器负责实例化.定位.配置应用程序中的对象及建立这些对象间的依赖.应用程序无需直接在代码中new相关的对象,应用程序由IoC ...
随机推荐
- Superset 0.37 发布——颜值最高的数据可视化平台
Superset 0.37,增加可视化插件,行级权限控制 使用Superset已经有一段时间,其良好的体验与丰富的图表功能节省了大量的时间.但是对于权限,自定义图表,图表下载,报警邮件一直没有很好的支 ...
- js之按钮切换
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- istio 常见的 10 个异常
总结使用 istio 常见的10个异常: Service 端口命名约束 流控规则下发顺序问题 请求中断分析 sidecar 和 user container 启动顺序 Ingress Gateway ...
- CSS 常见样式 特殊用法 贯穿线&徽章&箭头
贯穿渐变线,中间插值 如图: <h3 class="brief-modal-title"> <span>公告</span> </h3> ...
- Win10系统安装Tensorflow-GPU和VSCode构建Tensorflow开发环境
[前言] 1. 最近因为上课需要安装Anaconda和Tensorflow-GPU,Anaconda安装很容易,但Tensorflow-GPU版本的安装较为复杂,因为需要考虑版本匹配的一些问题,很容易 ...
- 关于swagger
转自https://blog.csdn.net/sanyaoxu_2/article/details/80555328 1:认识Swagger Swagger 是一个规范和完整的框架,用于生成.描述. ...
- Docker:二、开始部署第一个Asp.net应用
各位看官大家好,接着上一篇,我们构建自己的镜像文件成功之后,准备开始部署自己的第一个docker应用了... 接着上文,我们构建自己的镜像,如下是Dockerfile文件 #引入运行环 ...
- selenium过豆瓣滑动验证码
首先是加速度代码 def get_tracks(distance): """ 拿到移动轨迹,模仿人的滑动行为,先匀加速后匀减速 匀变速运动基本公式: ①v = v0+at ...
- 为什么我选择MySQL Workbench・一
一.官方 官方提供的工具必然有其优势. MySQL Workbench有两个版本,社区版和商业版.社区版是免费的. 二.第一个选择 使用MySQL之前用的是SQL Server而微软的东西一般都使用微 ...
- dubbo学习(二)配置dubbo XML方式配置
provider(生产者) <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo= ...