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');