Laravel 依赖注入深入了解 门面模式 迭代器的使用 从零搭建laravel 框架

最近在学习 java  。 看java 入门到精通 。在反射部分 突然对以前不懂的 依赖注入 豁然开朗

依赖注入  就是通过反射 去获取对象中需要的参数 类

下面是模仿laravel 实现过程 。比较 low

 原创  转载请注明出处

https://github.com/Childdreams/laravelIoc 源码地址

<?php

/**
 *	依赖注入取决的 就是 容器和反射 两个部分
 *	可以考虑一个服务提供者  
 *	然后 在服务提供者进行注册
 *	服务提供者 在生命周期内
 *	进行注册 或者其他的操作 
 *	需要实现接口  
 *	接口 register 为注册 handle  为执行 boot 为监听
 */
namespace app;
use app\interfaces\RequestInterface;
use app\interfaces\SendSmsInterface;

/**
 *	实现接口
 */
class Request implements RequestInterface
{
    public $id = 0 ;
}

class SendSmsService implements SendSmsInterface 
{
	public $name = "This is sendSmsSevice ";
}
namespace app\interfaces;

/**
 *	接口类
 *	解耦使用
 */
interface RequestInterface{}

namespace app\interfaces;

interface SendSmsInterface {}

namespace bpp;

/**
 *	容器类
 */
class Container
{
    public $register = [];

    public function register(array $bind){
		foreach($bind as $concrete){
			if($concrete  !instanceof Closure){
				throw new Exception();
			}
		}
        $this->register = array_merge($this->register , $bind) ;
    }
}



namespace cpp;
use app\interfaces\RequestInterface;
use app\interfaces\SendSmsInterface;

/**
 * 控制器
 */
class UserController
{
    public function __construct()
    {
    }

    public function test(RequestInterface $request , SendSmsInterface $sendSmsService){
        var_dump($request->id);
        var_dump("this is 依赖注入");
		var_dump($sendSmsService->name);
    }
}

namespace test;

use bpp\Container;

//实例化容器
$api = new Container();
//将依赖注册到容器  , 此处用 接口模式 是为了 解耦合
$api->register([
	\app\interfaces\RequestInterface::class => \app\Request::class
]);
$api->register([
	\app\interfaces\SendSmsInterface::class => \app\SendSmsService::class
]);

// 模仿路由
$router = "cpp\UserController@test";
$routers = explode("@",$router);

// 将 控制器 反射 出来
$ref = (new \ReflectionClass($routers[0]));

// 获取 控制器的 方法 里面的参数
$refs = $ref->getMethod($routers[1])->getParameters();

$inject = [];

foreach ($refs as $re){
	
	//获取参数的类
    $class = $re->getClass()->name;
	// 在容器查询 是否注册过
    if (array_key_exists($class , $api->register)){
		// 获取 容器内注册的方法
		$class = $api->register[$class];
		//浅显易懂
        $classes = $ref->newInstance();
        $name = $routers[1];
		$inject[] = new $class();
    }else {
		throw new \Exception("bug");
	}
}

(new $classes())->{$name}(...$inject);

依赖注入

  • 理解

    依赖注入的实现方式就是 将需要注入的服务注册到容器内, 当路由访问一个控制器的时候 利用反射ReflectionClass 去获取需要注入的服务。然后将服务进行实例化注入

    代码实现部分

    $router = "cpp\UserController@test";
    $routers = explode("@", $router);
    
    // 将 控制器 反射 出来
    
    $ref = (new \ReflectionClass($routers[0]));
    
    
    // 获取 控制器的 方法 里面的参数
    $refs = $ref->getMethod($routers[1])->getParameters();
    
    $inject = [];
    foreach ($refs as $re) {
      //获取参数的类
      $class = $re->getClass()->name;
      // 在容器查询 是否注册过
      if (array_key_exists($class, $app->register)) {
          // 获取 容器内注册的方法
          $class = $app->register[$class];
          //浅显易懂
          $name = $routers[1];
          $inject[] = new $class();
      } else {
          throw new \Exception("bug");
      }
    }
    $classes = $ref->newInstance();  // == new $ref
    call_user_func_array([$classes , $name] , ...$inject) ; 
    

    至于怎么注册到容器 laravel 的写法是 服务提供者。 将服务提供者注册到

    /config/app.php

    将服务提供者携带的 服务注册到 容器中 bootstrap/app.php line 23

    baofeng\Demo\Kernel\Kernel@reisterServiceProvider

门面模式

门面模式的核心内容 依旧是将门面模式的注入到容器之中 。在正常的 门面模式直接返回注入时候的key , 通过 __callstatic 去容器中查询

baofeng\Demo\Facaders\Facader

迭代器 IteratorAggregate

laravel 中 db 等 对象进行foreach 循环时候 ,循环出来的只是它想让你循环的东西 这时候就用到了

baofeng\Demo\Https\Request

baofeng\Demo\Iterators\MyIterator

详细的注释在 baofeng\Demo\Iterators\MyIterator 中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值