phprs\util\IoCFactory::create PHP Method

create() public method

根据id得到对象实例 TODO 单实例间互相引用会是问题
public create ( string $id, array $construct_args = null, array $properties = null, callable $injector = null, callable $init = null ) : object
$id string
$construct_args array 构造函数的参数
$properties array 类属性, 覆盖配置文件中的属性
$injector callable fun($src), 获取注入值的方法
$init callable fun($inst, &$got) 初始化实例, 在创建后, 调用构造函数前
return object
    public function create($id, $construct_args = null, $properties = null, $injector = null, $init = null)
    {
        if ($properties === null) {
            $properties = array();
        }
        if ($construct_args === null) {
            $construct_args = array();
        }
        $ins = null;
        $is_singleton = false;
        $class_name = $this->getClassName($id);
        if (isset($this->conf[$id])) {
            $class = $this->conf[$id];
            $class_refl = new \ReflectionClass($class_name);
            // 如果是单例
            // 带构造参数的类不支持单例
            if (count($properties) === 0 && count($construct_args) === 0 && isset($class['singleton']) && $class['singleton']) {
                $is_singleton = true;
                if (isset($this->singletons[$id])) {
                    $ins = $this->singletons[$id];
                    Logger::info("get {$id}[{$class_name}] as singleton");
                    return $ins;
                }
            }
            if (isset($class['properties'])) {
                $properties = array_merge($class['properties'], $properties);
            }
            if (isset($class['pass_by_construct']) && $class['pass_by_construct']) {
                //属性在构造时传入
                Verify::isTrue(count($construct_args) === 0, "{$class_name} pass_by_construct");
                //构造时传输属性, 所以不能再传入其他构造参数
                //组合构造参数
                $construct_args = $this->buildConstructArgs($class_refl, $properties);
                $properties = array();
            }
        } else {
            $class_refl = new \ReflectionClass($class_name);
        }
        if (!$is_singleton) {
            if (array_search($id, $this->create_stack) !== false) {
                $tmp = $this->create_stack;
                Verify::e("create {$id} failed, cyclic dependencies can only used with singleton. cyclic:" . print_r($tmp, true));
            }
            $this->create_stack[] = $id;
        }
        try {
            if (isset($class['pass_by_construct']) && $class['pass_by_construct']) {
                $ins = $class_refl->newInstanceArgs($construct_args);
                $meta = $this->getMetaInfo($class_refl);
                if ($is_singleton) {
                    $this->singletons[$id] = $ins;
                }
                $this->injectDependent($class_refl, $ins, $meta, $properties, $injector);
            } else {
                $nti = new NewThenInit($class_refl);
                $ins = $nti->getObject();
                $meta = $this->getMetaInfo($class_refl);
                if ($is_singleton) {
                    $this->singletons[$id] = $ins;
                }
                $this->injectDependent($class_refl, $ins, $meta, $properties, $injector);
                if ($init !== null) {
                    $init($ins);
                }
                $nti->initArgs($construct_args);
            }
        } catch (\Exception $e) {
            array_pop($this->create_stack);
            throw $e;
        }
        array_pop($this->create_stack);
        Logger::info("create {$id}[{$class_name}] ok");
        return $ins;
    }

Usage Example

Ejemplo n.º 1
0
 public function testCyclicDependenciesWithSingleton()
 {
     $factory = new IoCFactory(array('ClassA' => array('properties' => array('classB' => '@ClassB'), 'singleton' => true), 'ClassB' => array('properties' => array('classA' => '@ClassA'))));
     $classA = $factory->create('ClassA');
     $classB = $factory->create('ClassB');
     $this->assertInstanceOf('ClassB', $classA->classB);
     $this->assertInstanceOf('ClassA', $classB->classA);
     $this->assertSame($classB->classA, $classA);
 }
All Usage Examples Of phprs\util\IoCFactory::create