db80 / ovo-container
此包已被废弃,不再维护。未建议替代包。
PHP 5.3 轻量级依赖注入/控制反转框架
0.2.1
2012-10-08 10:38 UTC
Requires
- php: >=5.3.0
- doctrine/common: 2.3.0
This package is not auto-updated.
Last update: 2018-08-29 11:11:07 UTC
README
Ovo Container 是一个针对 PHP 5.3 的轻量级依赖注入/控制反转框架。
它受到 Spring 框架的启发,但它是纯 PHP 5.3 实现。
一些优秀的文章有
- https://martinfowler.com.cn/articles/injection.html
- http://www.theserverside.com/news/1321158/A-beginners-guide-to-Dependency-Injection
- http://www.vogella.de/articles/SpringDependencyInjection/article.html
主要目标
- 将行为与依赖解析分离,从而解耦高度依赖的组件。
- 易于单元测试和代码的可重用性
- 轻量级:"bean" 可以是任何 PHP 类(无需实现特定接口)
- 将您的应用程序仅集中在业务逻辑上
- 范围管理。单个类可以具有不同的 "bean" 范围
- 单例:将单个 bean 定义范围限定到应用程序请求结束(默认行为)。
- 原型:将单个 bean 定义范围限定到任意数量的对象实例。
- 会话:将单个 bean 定义范围限定到 HTTP 会话的生命周期(仅在 HTTP 上下文中)。
- 所有 bean 都可以在应用程序加载时创建或延迟创建(单例 bean 默认预初始化)
- 最小配置:XML 文件或 注释
- INI 文件用于配置参数
- 工厂、初始化和销毁方法
- PSR-0 兼容包。
- 示例和单元测试(PHPUnit)位于文件夹 "/test" 中。
如何安装
####使用 Composer
touch composer.json && echo '{"require": {"db80/ovo-container": "dev-master"},"minimum-stability": "dev"}' > composer.json composer.phar install --prefer-dist //include_once('vendor/autoload.php'); inside your application
####克隆项目,运行测试并构建您自己的应用程序
git clone https://github.com/db80/ovo-container.git && cd ovo-container/ composer.phar install --prefer-dist //the phpunit framework must be present in your classpath ./run-tests
Bean 示例
bean 是依赖注入容器中 "简单 PHP 对象" 的表示。每个单独的 bean 可以具有不同的范围和不同的名称(单例、原型 或 会话)。我们可以使用注释或 XML 文件来配置我们的应用程序。
注释样式
注释
namespace Ovo\Container\Test\Annotation; use Ovo\Container\Annotation\Bean; /** * @Bean(name= "prototypeSimpleRandom", scope = "prototype"); * @Bean(name= "sessionSimpleRandom", scope = "session"); * @Bean(name= "singletonSimpleRandom"); */ final class SimpleRandom { private $randomId = null; public function __construct() { $this->randomId = rand(0, 1000); } public function getRandomId() { return $this->randomId; } }
应用程序示例
use Ovo\Container\AnnotationContainer; use Ovo\Container\Test\Annotation\SimpleRandom $container = new AnnotationContainer('path/to/beans/annotation/folder'); //get a singleton instance of SimpleBean $singletonSimpleRandomA = $container->getBean('singletonSimpleRandom'); $singletonIdA = $singletonSimpleRandomA->getRandomId() $singletonSimpleRandomB = $container->getBean('singletonSimpleRandom'); $singletonIdB = $singletonSimpleRandomB->getRandomId() //$singletonIdA == $singletonIdB //$singletonSimpleRandomA == $singletonSimpleRandomB //get a prototype instance of SimpleBean $prototypeSimpleRandomA = $container->getBean('prototypeSimpleRandom'); $prototypeIdA = $prototypeSimpleRandomA->getRandomId(); $prototypeSimpleRandomB = $container->getBean('prototypeSimpleRandom'); $prototypeIdB = $prototypeSimpleRandomB->getRandomId(); //$singletonSimpleRandom != $prototypeSimpleRandom //$prototypeIdA != $prototypeIdB
XML 样式
XML 配置文件
<?xml version="1.0" encoding="utf-8" ?> <config> <bean name="singletonSimpleRandom" class="Ovo\Container\Test\Annotation\SimpleRandom" /> <bean name="prototypeSimpleRandom" class="Ovo\Container\Test\Annotation\SimpleRandom" scope="prototype"/> <bean name="sessionSimpleRandom" class="Ovo\Container\Test\Annotation\SimpleRandom" scope="session"/> </config>
应用程序示例
use Ovo\Container\XmlContainer; use Ovo\Container\Test\Annotation\SimpleRandom $container = new XmlContainer('path/to/xml/config/file.xml'); //get a singleton instance of SimpleBean $singletonSimpleRandom = $container->getBean('singletonSimpleRandom'); $singletonSimpleRandom->getRandomId() //get a prototypeSimpleRandom instance of SimpleBean $prototypeSimpleRandom = $container->getBean('prototypeSimpleRandom'); // $singletonSimpleRandom != $prototypeSimpleRandom
依赖注入
每个单独的 bean 可以有不同的 bean 依赖项(PHP 对象依赖项)。容器必须了解这些依赖项,以便以正确的方式创建 bean。
注释样式
注释
namespace Ovo\Container\Test\App; use Ovo\Container\Test\App\DataSource; use Ovo\Container\Test\App\ApplicationService; use Ovo\Container\Annotation\Bean; use Ovo\Container\Annotation\Dependency; /** * @Bean(name= "applicationService"); */ final class ApplicationServiceImpl implementes ApplicationService { /** * @Dependency(ref = "dataSource"); */ private $dataSource; private function __construct() { } public function getEmailByUserId($id) { return $this->dataSource->getUserById($id)->getEmail(); } //the setter is used to inject the dependency public function setDataSource(DataSource $dataSource) { $this->dataSource = $dataSource; } }
namespace Ovo\Container\Test\App; use Ovo\Container\Annotation\Bean; use Ovo\Container\Annotation\Param; /** * @Bean(name= "dataSource") */ final class DataSource { private $username; private $password; private $database; private $host; /** * @Param(type="string", name="my_username") * @Param(type="string", name="my_password") * @Param(type="string", name="my_database") * @Param(type="string", name="my_host") */ public function __construct($username, $password, $database, $host) { $this->username = $username; $this->password= $password; $this->database = $database; $this->host = $host; } public function getUserById($id) { //Business logic here } //other methods }
应用程序示例
use Ovo\Container\AnnotationContainer; use Ovo\Container\Test\App\DataSource use Ovo\Container\Test\App\ApplicationService $container = new AnnotationContainer('path/to/beans/annotation/folder'); $applicationService = $container->getBean('applicationService'); $email = $applicationService->getEmailByUserId($id)
XML 样式
XML 配置文件
<?xml version="1.0" encoding="utf-8" ?> <config> <!-- Application Service --> <bean name="applicationService" class="Ovo\Container\Test\App\ApplicationServiceImpl"> <properties> <value name="dataSource" ref="dataSource"/> </properties> </bean> <bean name="dataSource" class="Ovo\Container\Test\App\DataSource"> <construct> <value name="my_username" type="string"/> <value name="my_password" type="string"/> <value name="my_database" type="string"/> <value name="my_host" type="string"/> </construct> </bean> </config>
应用程序示例
use Ovo\Container\XmlContainer; use Ovo\Container\Test\App\DataSource use Ovo\Container\Test\App\ApplicationService $container = new XmlContainer('path/to/xml/config/file.xml'); $applicationService = $container->getBean('applicationService'); $email = $applicationService->getEmailByUserId($id)
INI 文件用于存储应用程序属性
在现实生活中,将应用程序参数(如密码或 URL)存储在单独的文件中非常有用。假设我们有一个如下所示的文件
username = daniele password = pa$$w0rd host = localhost
容器可以使用通用的 .ini 文件在创建 bean 时绑定我们的应用程序参数。
标注样式
注释
namespace Ovo\Container\Test\App; use Ovo\Container\Annotation\Bean; use Ovo\Container\Annotation\Param; /** * @Bean(name= "emailReader") */ final class EmailReader { private $username; private $password; private $host; /** * @Param(type="string", name="[$username]") * @Param(type="string", name="[$password]") * @Param(type="string", name="[$host]") */ public function __construct($username, $password, $host) { $this->username = $username; $this->password= $password; $this->host = $host; } public function checkNewEmails() { //business logic here } }
应用程序示例
use Ovo\Container\AnnotationContainer; use Ovo\Container\Test\App\EmailReader use Ovo\Container\Test\App\ApplicationService $container = new AnnotationContainer('path/to/beans/annotation/folder', 'path/to/ini/config.ini'); $emailReader = $container->getBean('emailReader'); $emailReader->checkNewEmails();
XML样式
XML 配置文件
<?xml version="1.0" encoding="utf-8" ?> <config> <!-- Application Service --> <bean name="emailReader" class="Ovo\Container\Test\App\DataSource\EmailReader"> <construct> <value name="[$username]" type="string"/> <value name="[$password]" type="string"/> <value name="[$host]" type="string"/> </construct> </bean> </config>
应用程序示例
use Ovo\Container\XmlContainer; use Ovo\Container\Test\App\EmailReader use Ovo\Container\Test\App\ApplicationService $container = new XmlContainer('path/to/xml/config/file.xml', 'path/to/ini/config.ini'); $emailReader = $container->getBean('emailReader'); $emailReader->checkNewEmails();
工厂方法
DI容器支持通过静态工厂方法创建bean。
标注样式
注释
namespace Ovo\Container\Test\Annotation; use Ovo\Container\Annotation\Bean; use Ovo\Container\Annotation\FactoryMethod; /** * @Bean(name= "prototypeSimpleRandom", scope = "prototype"); */ final class SimpleRandom { private $randomId; private function __construct() { $this->randomId = rand(0, 1000); } /** * @FactoryMethod */ public static function getInstance() { return new self(); } public function getRandomId() { return $this->randomId; } }
应用程序示例
use Ovo\Container\AnnotationContainer; use Ovo\Container\Test\Annotation\SimpleRandom $container = new AnnotationContainer('path/to/beans/annotation/folder'); //get a singleton instance of SimpleBean $singletonSimpleRandom = $container->getBean('singletonSimpleRandom'); $singletonID = $singletonSimpleRandom->getRandomId() //$singletonID is int
XML样式
XML 配置文件
<?xml version="1.0" encoding="utf-8" ?> <config> <bean name="prototypeSimpleRandom" class="Ovo\Container\Test\Annotation\SimpleRandom" factory-method='getInstance' scope="prototype"/> </config>
应用程序示例
use Ovo\Container\XmlContainer; use Ovo\Container\Test\Annotation\SimpleRandom $container = new XmlContainer('path/to/xml/config/file.xml'); //get a singleton instance of SimpleBean $singletonSimpleRandom = $container->getBean('singletonSimpleRandom'); $singletonID = $singletonSimpleRandom->getRandomId() //$singletonID is int
初始化和销毁方法
有时我们需要在bean创建后调用初始化方法(或在容器关闭前调用销毁方法)。DI容器可以为我们完成这个任务。
标注样式
注释
namespace Ovo\Container\Test\Annotation; use Ovo\Container\Annotation\Bean; use Ovo\Container\Annotation\DestroyMethod; use Ovo\Container\Annotation\InitMethod; use Ovo\Container\Annotation\FactoryMethod; /** * @Bean(name= "prototypeSimpleRandom", scope = "prototype"); */ final class SimpleRandom { private $randomId = null; public function __construct() { } public function getRandomId() { return $this->randomId; } /** * @InitMethod */ public function generateId() { $this->randomId = rand(0, 1000); } /** * @DestroyMethod */ public function close() { $this->randomId = null; } }
应用程序示例
use Ovo\Container\AnnotationContainer; use Ovo\Container\Test\Annotation\SimpleRandom $container = new AnnotationContainer('path/to/beans/annotation/folder'); //get a singleton instance of SimpleBean $singletonSimpleRandom = $container->getBean('singletonSimpleRandom'); $singletonID = $singletonSimpleRandom->getRandomId() //$singletonID is int $container->close(); $singletonID = $singletonSimpleRandom->getRandomId() //$singletonID is null
XML样式
XML 配置文件
<?xml version="1.0" encoding="utf-8" ?> <config> <bean name="prototypeSimpleRandom" class="Ovo\Container\Test\Annotation\SimpleRandom" init-method="generateId" destroy-method="close" factory-method='getInstance' scope="prototype"/> </config>
应用程序示例
use Ovo\Container\XmlContainer; use Ovo\Container\Test\Annotation\SimpleRandom $container = new XmlContainer('path/to/xml/config/file.xml'); //get a singleton instance of SimpleBean $singletonSimpleRandom = $container->getBean('singletonSimpleRandom'); $singletonID = $singletonSimpleRandom->getRandomId() //$singletonID is int $container->close(); $singletonID = $singletonSimpleRandom->getRandomId() //$singletonID is null