gears/di

此包已被 废弃,不再维护。没有推荐替代包。

gears 依赖注入容器。

v0.2.1 2014-11-21 05:21 UTC

This package is not auto-updated.

Last update: 2019-02-20 18:13:27 UTC


README

Build Status Latest Stable Version Total Downloads License

我们所有人都听说过这个叫做依赖注入的东西。它在 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