zoukankan      html  css  js  c++  java
  • 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();
  • 相关阅读:
    markdown图片设置
    编程变量名
    c++ 子类构造函数初始化及父类构造初始化
    idea中解决Git反复输入代码的问题
    idea中修改git提交代码的用户名
    网络相关
    idea Controller层编译Mapper层报错
    java7与java8的新特性
    修改列名以及其数据类型
    修改数据库表的某个字段默认值
  • 原文地址:https://www.cnblogs.com/paulversion/p/11703522.html
Copyright © 2011-2022 走看看