selene / di
Selene 依赖注入组件
Requires
- php: >=5.4.0
- selene/common: dev-development
- selene/writer: dev-development
Requires (Dev)
- league/phpunit-coverage-listener: dev-master
- phpunit/phpunit: ~4.0
- selene/config: dev-development
- selene/testsuite: dev-development
Suggests
This package is not auto-updated.
Last update: 2016-02-07 09:58:41 UTC
README
<?php use Selene\Components\DI; $container = new Container;
使用
参数
<?php
$container->setParameter('my.param', 'param value');
$container->setParameter('my.options', [1, 2, 3]);
$container->getParameter('my.param'); // 'param value'
$container->getParameter('my.options'); // [1, 2, 3]
定义服务
<?php
$container->define('my.service', 'ServiceClass', ['service args']);
将类实例注入为服务
在某些情况下,可能无法或不需要容器创建服务。因此,您可以将类实例作为服务注入。
<?php
$container
->define('service_id', 'InjectedClass')
->setInjected(true);
// ...
$container->inject('service_id', $instance);
同步注入服务上的依赖如果您的服务依赖于另一个被注入的服务,您不能依赖该依赖在服务构造函数上声明。相反,您应该使用以下描述的setter注入。依赖于注入服务的setter仅在所有依赖都解决后才会调用。
注入
构造函数注入<?php
$container->setParameter('my.param', 'param value');
// passing a parameter to the constructor of a service:
$container->define('my_service', 'Acme\FooService', ['%my.param%']);
// or
$container->define('my_service', 'Acme\FooService')
->addArgument('%my.param%');
// passing a service reference to the constructor of a service:
$container->define('other_service', 'Acme\OtherService');
$container->define('my_service', 'Acme\ServiceNeedsOtherService', ['$other_service']);
// or
$container->define('my_service', 'Acme\ServiceNeedsOtherService')
->addArgument('$other_service');
注意服务ID前面的 $ 符号。 $ 将表示您正在引用一个服务。您也可以创建一个引用对象而不是使用美元符号。
<?php
use \Selene\Components\DI\Reference;
$container->define('my_service', 'Acme\ServiceNeedsOtherService')
->addArgument(new Reference('other_service'));
setter注入<?php
$container->setParameter('my.options', [1, 2, 3]);
// passing a parameter to a setter method of a service
$container->define('my_service', 'Acme\FooService')
->addSetter('setOptions', ['%my.options%'])
// passing a service reference to a setter method of a service
$container->define('other_service', 'Acme\OtherService');
$container->define('my_service', 'Acme\ServiceNeedsOtherService')
->addSetter('setOtherService', ['%other_service%']);
工厂有时您可能发现使用工厂启动服务更容易。对于DIC来说,工厂是一个接收某些(或没有)参数的类方法,并返回您的服务实例。
工厂方法可以是静态的或非静态的。在服务定义上声明的所有参数都将注入到工厂方法中。
<?php
namespace Acme\Foo;
class ServiceFactory
{
public function makeFooService($fooargs = null)
{
return new FooService($fooargs);
}
}
<?php
$container->setParameter('foo.options', ['opt1', 'opt2']);
$container->setParameter('foo.factory.class', 'Acme\Foo\ServiceFactory');
$container
->setService('foo_service')
->setFactory('%foo.factory.class%', 'makeFooService')
->addArgument('%foo.options%');
作用域
目前有两种不同的作用域,即 container 和 prototype。服务默认为 container 创建。您可以通过设置相应的范围来覆盖此设置。
请注意,您不能将注入服务的范围更改为 prototype。
<?php
$container->define('my_service', 'Acme\FooService')
->setScope(ContainerInterface::SCOPE_PROTOTYPE);
服务和容器作用域使用 container 范围定义的服务将在每次调用服务时返回相同的实例。
与容器范围不同,将服务的范围设置为 prototype 将在每次调用时创建该服务的新实例。
解析服务
所有服务都是懒加载的。服务是在第一次调用时解析的。
<?php
$service = $container->get('my_service');
别名
服务也可以通过别名进行别名化和解析。
<?php
$container->alias('my_service', 'my_alias');
服务继承
您可以从父服务继承依赖项。父服务可以是具体的或抽象的。
请注意,子服务将继承从其父服务继承的构造函数和setter注入依赖项。
<?php
$container->setParameter('Acme\AbstractServiceClass', ['$foo_service']);
$container
->define('parent_service', 'Acme\ConcreteServiceClass')
->setAbstract()
->addArgument('foo');
$container
->define('concrete_service', 'Acme\ConcreteServiceClass')
->setParent(new Reference('parent_service'));
构建容器
动态依赖注入会带来一定的开销。然而,从动态容器中构建静态容器是可行的。在将 DIC 应用于生产环境时,这非常有用。
<?php use Selene\Components\DI\Builder; $builder = new Builder($container); $builder->build();
配置
可以使用文件加载器配置 DIC
使用 XML 进行配置
示例 XML
<?xml version="1.0" encoding="UTF-8"?>
<container>
<parameters>
<parameter id="service.class">Acme\Foo</parameter>
</parameters>
<services>
<service id="service" class="%service.class%"/>
</services>
</container>
<?php
use Selene\Components\DI\Builder;
use Selene\Components\DI\Loader\XmlLoader;
use Selene\Components\Config\Resource\Locator;
$loader = new XmlLoader($builder = new Builder($container), new Locator($paths));
$loader->load('services.xml');