gears / di
此包已被 废弃,不再维护。没有推荐替代包。
gears 依赖注入容器。
v0.2.1
2014-11-21 05:21 UTC
Requires (Dev)
- codegyre/robo: *
- mockery/mockery: *
- phpunit/phpunit: 4.*
This package is not auto-updated.
Last update: 2019-02-20 18:13:27 UTC
README
我们所有人都听说过这个叫做依赖注入的东西。它在 Java、.Net 等其他企业环境中已经存在了很长时间。但它在 PHP 世界中还是相对较新的。
大多数人都会理解这个概念,但如果不懂,可以查看
如何安装
通过 composer 安装很简单
composer require gears/di:*
如何使用
首先,这个容器类似于 Pimple,但它并不是 Pimple。它有一些独特之处,所以请注意。
基本示例
// lets import the class use Gears\Di\Container; // create a new container object $container = new Container(); // define some services $container['session_storage'] = function () { return new SessionStorage('SESSION_ID'); }; $container['session'] = function () { return new Session($this['session_storage']); }; // get the session object $session = $container['session']; // define factory service $container['session_factory'] = $container->factory(function() { return new Session($this['session_storage']); }); // define container parameters / attributes $container['cookie_name'] = 'SESSION_ID'; // protecting parameters $container['random_func'] = $container->protect(function() { return rand(); });
对于之前使用过 Pimple 容器的人来说,你应该注意,容器不是通过函数参数传递的,而是可以通过
$this
变量访问。这是因为我们将闭包绑定到容器上。
使用服务提供者
use Gears\Di\Container; use Gears\Di\ServiceProviderInterface; class FooProvider implements ServiceProviderInterface { public function register(Container $c) { $c['FooService'] = function(){ return new Foo(); }; } } $container = new Container(); $container->register(new FooProvider()); $container['FooService']->bar();
对象语法
// you can also use the container like this. $container = new Container(); $container->session_storage = function () { return new SessionStorage('SESSION_ID'); }; $container->session = function () { return new Session($this->session_storage); }; $session = $container->session;
扩展容器
class Mail extends Container { // note how we prefix the word inject. // this tells us that the property is injectable protected $injectTo; // private properties however will always be // private and can not be injected directly. private $sendMailPath; // so if you tried to inject fooBar it will fail private $injectFooBar; // from a naming standpoint I think it is best if you name the injectable // properties such that it tells you the type that should be injected. // however this isn't enforced. protected $injectMessage; protected $injectTransportService; // this is where we can define default services for our container. protected function setDefaults() { // notice how we set them without the word inject $this->to = 'brad@bjc.id.au'; // I could have defined this above directly on the property // but I would rather keep everything consistent. $this->sendMailPath = '/bin/sendmail'; $this->message = function() { return new Message('Hello World'); }; // take note of the camel case property name vs the definition above. $this->transportService = function() { return new SendMailTransport($this->sendMailPath); }; // you can use factory and protect too // note you don't have to explicitly define a class property. // but just note that both abc and xyz are public properties. $this->abc = $this->factory(function(){ return new Abc(); }); $this->xyz = $this->protect(function($a,$b){ return $a+$b; }); } public function send() { $this->message->setTo($this->to); return $this->transportService->send($this->message); } } $mail = new Mail(); $mail->send(); // sends an email to me saying Hello World $mail = new Mail(); $mail->to = 'foo@example.com'; $mail->ip = '127.0.0.1'; $mail->message = function(){ return new Message('bar'); }; $mail->transportService = function(){ return new SmtpTransport($this->ip); }; $mail->send(); // sends an email to foo@example.com via 127.0.0.1 saying bar // the above could be re written as $mail = new Mail ([ 'to' => 'foo@example.com', 'ip' => '127.0.0.1', 'message' => function(){ return new Message('bar'); }, 'transportService' => function(){ return new SmtpTransport($this->ip); }, ]); $mail->send();
致谢
这无疑受到了 Fabien 的 Pimple Di Container 的启发。 http://pimple.sensiolabs.org/
由 Brad Jones 开发 - brad@bjc.id.au