avz-cmf/zaboy-dic

DI - InsideConstruct

1.1.0 2017-01-10 10:07 UTC

This package is not auto-updated.

Last update: 2024-09-14 19:31:29 UTC


README

目录

文档

##快速入门

###常规实践

假设我们有一个类,它接受3个服务作为依赖项

class Class1
{
    public $propA;
    public $propB;
    public $propC;

    public function __construct($propA = null, $propB = null, $propC = null)
    {
        $this->propA = $propA;
        $this->propB = $propB;
        $this->propC = $propC;
    }
}

/* @var $contaner ContainerInterface */
global $contaner;
$propA = $contaner->has('propA') ? $contaner->get('propA') : null;
$propB = $contaner->has('propB') ? $contaner->get('propB') : null;
$propC = $contaner->has('propC') ? $contaner->get('propC') : null;

new Class1($propA, $propB, $propC);

我们从容器中获取依赖项,并将它们赋值给对象的同名属性。

###现在使用 InsideConstruct::initServices() 做同样的事情

如果参数名与服务名和对象属性名相匹配

class Class1
{

    public $propA;
    public $propB;
    public $propC;

    public function __construct($propA = null, $propB = null, $propC = null)
    {
        InsideConstruct::initServices();
    }

}

new Class1();

所有三个服务将按上面的示例从 $container 中初始化。
调用 InsideConstruct::initServices() 不会改变传递给构造函数的参数。
如果构造函数参数指定了类型或接口,则通过调用 InsideConstruct::initServices() 获得的服务将进行检查以匹配。
初始化 PublicProtectedPrivate 对象属性。不会初始化 Static 属性和祖先的 Private 属性。

##使用

IInsideConstruct::initServices(); 方法返回什么

返回一个数组 ['param1Name'=>value1', 'param2Name' => 'value2', ...]

如何覆盖默认值

如果这样

        new Class1(new stdClass(), null);

则只有一个(最后的)参数将被初始化为服务 $container->get('propC')
另外两个将获得 new stdClass()null 的值。但对象属性赋值或调用设置器(见下文)将对所有参数起作用。

设置器 ($this->setPropA($value))

如果为构造函数参数定义了相应的(按名称)设置器 - 则会调用它。设置器优于属性。如果参数既有设置器又有属性,则调用设置器,而不会对属性进行赋值。

如果涉及继承呢?

假设我们有基类

class Class0
{
	public $propA;

    public function __construct($propA = null)
    {
            InsideConstruct::initServices();
	}
}

$class0 = new Class0;        // $class0->propA = $container->get('propA');

,我们需要更改使用的服务: // $class0->propA = $container->get('newPropA');
可以这样

class Class1 extends Class0
{
    public function __construct($newPropA = null)
    {
            $params = InsideConstruct::initServices(['newPropA']);
			$propA = $params['newPropA'];
			parent::__construct(propA);
	}
};

调用参数

在上面的例子中,InsideConstruct::initServices(['newPropA']); 添加了调用参数 'newPropA'。
为什么需要这样?因为对象 Class1 没有属性 $this->newPropA 或方法 $this->setNewPropA()。并且它不会尝试在参数未传递给构造函数的情况下加载服务 'newPropA'。
传递参数 InsideConstruct::initServices(['newPropA']); 明确指示 initServices() 加载服务 'newPropA'

再次简要总结一下要点

如果有相应的设置器或属性 - 值将被分配。
如果参数已传递(即使 NULL) - 则不会从容器加载服务。
如果参数未传递,则如果存在设置器、属性或在函数调用参数的 InsideConstruct::initServices([...]); 调用参数中指定了属性名,则将从容器加载服务。