zoukankan      html  css  js  c++  java
  • [PHP] 理解依赖注入容器-自动注入

    原文地址:

    PHP反射机制实现自动依赖注入 - 知乎 (zhihu.com)

    利用反射类获取类的对象,当有依赖其他类的时候,利用反射类获取到被依赖的对象,自动注入进来

    A依赖 B ===> B依赖C

    class C{
        public function __construct()
        {
        }
        public function doC(){
            echo "C";
        }
    }
    class B{
        protected $c;
        public function __construct(C $c)
        {
            $this->c=$c;
        }
    }
    class A{
        protected $b;
        public function __construct(B $b)
        {
            $this->b=$b;
        }
        public function doC(C $c){
            $c->doC();
        }
    }

    使用反射类通过类名获取到被依赖的对象,直接通过构造函数或者类方法注入

    /**
     *
     * 工具类,使用该类来实现自动依赖注入。
     *
     */
    class Ioc {
        // 获得类的对象实例
        public static function getInstance($className) {
            $paramArr = self::getMethodParams($className);
            return (new ReflectionClass($className))->newInstanceArgs($paramArr);
        }
        /**
         * 执行类的方法
         * @param  [type] $className  [类名]
         * @param  [type] $methodName [方法名称]
         * @param  [type] $params     [额外的参数]
         * @return [type]             [description]
         */
        public static function make($className, $methodName, $params = []) {
            // 获取类的实例
            $instance = self::getInstance($className);
            // 获取该方法所需要依赖注入的参数
            $paramArr = self::getMethodParams($className, $methodName);
            return $instance->{$methodName}(...array_merge($paramArr, $params));
        }
    
        /**
         * 获得类的方法参数,只获得有类型的参数
         * @param  [type] $className   [description]
         * @param  [type] $methodsName [description]
         * @return [type]              [description]
         */
        protected static function getMethodParams($className, $methodsName = '__construct') {
            // 通过反射获得该类
            $class = new ReflectionClass($className);
            $paramArr = []; // 记录参数,和参数类型
            // 判断该类是否有构造函数
            if ($class->hasMethod($methodsName)) {
                // 获得构造函数
                $construct = $class->getMethod($methodsName);
                // 判断构造函数是否有参数
                $params = $construct->getParameters();
                if (count($params) > 0) {
                    // 判断参数类型
                    foreach ($params as $key => $param) {
                        if ($paramClass = $param->getClass()) {
                            // 获得参数类型名称
                            $paramClassName = $paramClass->getName();
                            // 获得参数类型
                            $args = self::getMethodParams($paramClassName);
                            $paramArr[] = (new ReflectionClass($paramClass->getName()))->newInstanceArgs($args);
                        }
                    }
                }
            }
            return $paramArr;
        }
    }
    $a=Ioc::getInstance("A");
    var_dump($a);
    
    
    Ioc::make("A","doC");

    开源作品

    GO-FLY,一套可私有化部署的免费开源客服系统,安装过程不超过五分钟(超过你打我 !),基于Golang开发,二进制文件可直接使用无需搭开发环境,下载zip解压即可,仅依赖MySQL数据库,是一个开箱即用的网页在线客服系统,致力于帮助广大开发者/中小站长快速整合私有客服功能
    github地址:go-fly
    官网地址:https://gofly.sopans.com

    赞赏作者

    微信交流

  • 相关阅读:
    Attach Files to Objects 将文件附加到对象
    Provide Several View Variants for End-Users 为最终用户提供多个视图变体
    Audit Object Changes 审核对象更改
    Toggle the WinForms Ribbon Interface 切换 WinForms 功能区界面
    Change Style of Navigation Items 更改导航项的样式
    Apply Grouping to List View Data 将分组应用于列表视图数据
    Choose the WinForms UI Type 选择 WinForms UI 类型
    Filter List Views 筛选器列表视图
    Make a List View Editable 使列表视图可编辑
    Add a Preview to a List View将预览添加到列表视图
  • 原文地址:https://www.cnblogs.com/taoshihan/p/14900972.html
Copyright © 2011-2022 走看看