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的依赖注入已经是一个很常见的概 ...
随机推荐
- libevent实现对管道的读写操作
读管道: #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/t ...
- DFS解决八皇后问题
2019-07-29 16:49:15 #include <bits/stdc++.h> using namespace std; ][]; int tot; int check(int ...
- net core quartz调度 warp打包 nssm部署到windowsservice
介绍下一款vue.js实现的基于core2.1 quartz.net调度框架,独立部署不依赖数据库,只需要实现不同业务接口,配置调度时间即可 github:https://github.com/cq- ...
- (转)数据库函数解析JSON字符串
一.返回单行单列 二.返回表 三.SQL206版本开始支持 SELECT * FROM OPENJSON(@JsonStr)
- 匿名对象序列化为XML
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.X ...
- Thomas Brinkhoff 基于路网的移动对象生成器的使用[第二版]
Thomas Brinkhoff 基于路网的移动对象生成器的使用 Thomas Brinkhoff 基于路网的移动对象生成器的使用 相关操作的说明 相关文件的说明 运行 导入eclipse后运行时选择 ...
- java第三次面试总结
这次面试是二面,由于自己的经验不足,面试的结果不是很令人满意,所以与这家公司失之交臂,在这里记录一下经历,吸取教训. 之前的一面是笔试+面试,面试是主管,今天的面试是总监.在前台招待我的时候,还跟我说 ...
- 【UVA1505】 Flood-it!(IDA*)
题目链接 IDA*,估价函数为当前除了左上角的连通块以外颜色的种类数,因为每次最多消去一个颜色. 维护位于当前连通块的边缘但颜色不同的点,每次从这些点拓展就行. #include <cstdio ...
- 关于Eclipse导入maven项目报空指针异常
今天新建了一个maven项目,因为是通过公司的工具新建的,代码拉下来就有src.pom.xml文件. 导入Eclipse却报空指针异常.具体如下: An error has occurred. See ...
- input里面的提示文字修改(placeholder里的文字修改,el-input也适用)
input::-webkit-input-placeholder { /* WebKit browsers */ color: red; } input:-moz-placeholder { /* M ...