laravel 依赖注入
<?php
interface Animal{ public function attack();
public function talk(); } class People implements Animal
{
public $month;
public $hand;
public function __construct(Mouth $mouth,Hand $hand)
{
$this->month = $mouth;
$this->hand = $hand; } public function attack()
{
$this->hand->scrap();
} public function talk()
{
$this->month->say();
} } class Mouth{
public function say(){
echo "咿咿呀呀";
}
}
class Hand{
public $finger;
public function __construct(Finger $finger)
{
$this->finger = $finger;
} public function scrap(){
echo '仍玩具';
} public function otherFunction(){
$this->finger->eatFinger();
}
} class Finger{
public function eatFinger(){
echo "吃手指";
}
} class Container
{
/**
* 容器绑定,用来装提供的实例或者 提供实例的回调函数
* @var array
*/
public $building = []; /**
* 注册一个绑定到容器
*/
public function bind($abstract, $concrete = null, $shared = false){
if(is_null($concrete)){
$concrete = $abstract;
} if(!$concrete instanceOf Closure){
$concrete = $this->getClosure($abstract, $concrete);
} $this->building[$abstract] = compact("concrete", "shared");
} //注册一个共享的绑定 单例
public function singleton($abstract, $concrete, $shared = true){
$this->bind($abstract, $concrete, $shared);
} /**
* 默认生成实例的回调闭包
*
* @param $abstract
* @param $concrete
* @return Closure
*/
public function getClosure($abstract, $concrete){
return function($c) use($abstract, $concrete){
$method = ($abstract == $concrete)? 'build' : 'make';
return $c->$method($concrete);
};
} /**
* 生成实例
*/
public function make($abstract){
$concrete = $this->getConcrete($abstract); if($this->isBuildable($concrete, $abstract)){
$object = $this->build($concrete);
}else{
$object = $this->make($concrete);
} return $object;
} /**
* 获取绑定的回调函数
*/
public function getConcrete($abstract){ if(! isset($this->building[$abstract])){
return $abstract;
} return $this->building[$abstract]['concrete'];
} /**
* 判断 是否 可以创建服务实体
*/
public function isBuildable($concrete, $abstract){ return $concrete === $abstract || $concrete instanceof Closure;
} /**
* 根据实例具体名称实例具体对象
*/
public function build($concrete){ if($concrete instanceof Closure){
return $concrete($this);
} //创建反射对象
$reflector = new ReflectionClass($concrete);//通过反射获取类名 if( ! $reflector->isInstantiable()){
//抛出异常
throw new \Exception('无法实例化');
} $constructor = $reflector->getConstructor();//获取构造函数
if(is_null($constructor)){
return new $concrete;
} $dependencies = $constructor->getParameters();//获取构造函数参数
$instance = $this->getDependencies($dependencies);
return $reflector->newInstanceArgs($instance);//将参数注入到对象中 } //通过反射解决参数依赖
public function getDependencies(array $dependencies){
$results = [];
foreach( $dependencies as $dependency ){
$results[] = is_null($dependency->getClass())
?$this->resolvedNonClass($dependency)
:$this->resolvedClass($dependency);
} return $results;
} //解决一个没有类型提示依赖
public function resolvedNonClass(ReflectionParameter $parameter)
{
if($parameter->isDefaultValueAvailable()){
return $parameter->getDefaultValue();
}
throw new \Exception('出错'); } //通过容器解决依赖
public function resolvedClass(ReflectionParameter $parameter)
{
return $this->make($parameter->getClass()->name); } }
//实例化容器类
$container = new Container();
$container->bind('Animal','People');//将需要创建对象的类放到容器中
$people = $container->make('Animal');//创建对象
$people->attack();//调用方法
$people->talk();
laravel 依赖注入的更多相关文章
- Laravel 依赖注入原理
众所周知 Laravel 的文档对于依赖注入只写了如何使用,相信大多数人对于他的实现原理并不太清楚.虽然使用过程中并不需要关心她的原理,但是了解原理让你使用起来更自信.这个帖子就通过一个小 demo ...
- laravel依赖注入 容器
[看完就懂]Laravel 服务容器,IoC,DI DI DI就是常说的依赖注入,那么究竟什么是依赖注入呢? 打个比方,电脑(非笔记本哈)需要键盘和鼠标我们才能进行操作,这个‘需要’换句话说 ...
- php+laravel依赖注入浅析
laravel容器包含控制反转和依赖注入,使用起来就是,先把对象bind好,需要时可以直接使用make来取就好. 通常我们的调用如下. $config = $container->make('c ...
- laravel依赖注入浅析
laravel容器包含控制反转和依赖注入,使用起来就是,先把对象bind好,需要时可以直接使用make来取就好. 通常我们的调用如下. $config = $container->make('c ...
- laravel 依赖注入 接口设计
假设我现在需要做一个支付服务,那么我先设计一个接口 interface PayInterface{ public function pay(Order $order) : string; } 然后实现 ...
- 【转】理解 PHP 依赖注入 | Laravel IoC容器
Laravel框架的依赖注入确实很强大,并且通过容器实现依赖注入可以有选择性的加载需要的服务,减少初始化框架的开销,下面是我在网上看到的一个帖子,写的很好拿来与大家分享,文章从开始按照传统的类设计数据 ...
- 通过laravel理解IoC(控制反转)容器和DI(依赖注入)
原文地址: http://www.insp.top/learn-laravel-container ,转载务必保留来源,谢谢了! 容器,字面上理解就是装东西的东西.常见的变量.对象属性等都可以算是容器 ...
- 理解PHP 依赖注入|Laravel IoC容器
看Laravel的IoC容器文档只是介绍实例,但是没有说原理,之前用MVC框架都没有在意这个概念,无意中在phalcon的文档中看到这个详细的介绍,感觉豁然开朗,复制粘贴过来,主要是好久没有写东西了, ...
- laravel框架中所用到的依赖注入
用Laravel开发前前后后有2个月左右了,之前一直写Java,就像找到Java和PHP之前的共同点,用Java的某些原理去理解PHP会发现还是有很多共通之处的.Java的依赖注入已经是一个很常见的概 ...
随机推荐
- Oracle VM VirtualBox安装配置虚拟机Redhat7.6
首先,准备好材料,需要下载Oracle VM VirtualBox.Oracle19C的安装包.Redhat7.6镜像 下面列出地址: Oracle VM VirtualBox安装包:链接:https ...
- CF28B pSort
题目描述 给定一个含有n个元素的数列,第i号元素开始时数值为i,元素i可以与距离为d[i]的元素进行交换.再给定一个1-n的全排列,问初始的数列可否交换成给定的样式. 输入:第一行一个整数n,第二行n ...
- 使用GIT上传文件,VSCODE使用GIT上传项目
GIT使用方法: 1.安装git 2.设置用户名和邮箱: git config --global user.name="haokan1113" git config --globa ...
- Ubuntu19.04 Help
Ubuntu Dock 为应用程序启用最小化操作,立即生效. $ gsettings set org.gnome.shell.extensions.dash-to-dock click-action ...
- python 坑1
目录 1.编码解码 2.基础数据类型补充: 2.1 str: 2.2list: 2.3tuple: 2.4dict: 2.5set: 3.坑 4.类型转换: 5.数据类型: 1.编码解码 编码:将文字 ...
- caurina缓动类
一.简单的缓动 一个实例名为box的正方体,开始alpha为0.5,在两秒内移动到x:300 y:100的位置,alpha变为1.import caurina.transitions.Tweener; ...
- Spring Cloud Alibaba学习笔记(19) - Spring Cloud Gateway 自定义过滤器工厂
在前文中,我们介绍了Spring Cloud Gateway内置了一系列的内置过滤器工厂,若Spring Cloud Gateway内置的过滤器工厂无法满足我们的业务需求,那么此时就需要自定义自己的过 ...
- java mybatis
mybatis简单使用记录一下 mybatis官网:http://www.mybatis.org/mybatis-3/ 参考博客:https://blog.csdn.net/iku5200/artic ...
- c#部分类
c#提供了一个部分类,它只显示类的一部分,用关键字partical修饰 using System; public partial class Course { public int Id { get; ...
- Python接口自动化基础---get请求
1.没有参数的get请求 import requests r=requests.get('http://docs.python-requests.org/zh_CN/latest/user/quick ...