andyleap/popple

受 Pimple 启发的简单依赖注入容器

0.2.0 2013-08-05 18:46 UTC

This package is not auto-updated.

Last update: 2024-09-23 13:42:02 UTC


README

开发

Build Status

受 Pimple 启发的简单 PHP 依赖注入容器。

Popple 相较于 Pimple 的简洁性,提供了哪些优势?

非常简单,Popple 试图保持相同级别的简洁性,同时提供额外的功能,使其更易于使用。

例如,使用 Pimple 扩展服务需要几个步骤和一些额外的工作,因为你必须扩展该服务,然后共享它。

在 Popple 中,这一切都为你处理了。Popple 认为一切都是共享的,所以首先你创建服务。

$popple = new Popple();

$popple->Share('db', function($p)
{
  $db = new Popple();
	$db->Extend('Connect', function()
	{
		if(!isset($this['username']))
		{
			die('Username required!');
		}
		echo 'Connecting as ' . $this['username'];
	});
	return $db;
});

这创建了一个简单的服务,是主 $popple 实例。它被简单地访问和使用

$popple['db']['username'] = 'guest';
$popple['db']->Connect();

这也展示了 Popple 的另一个特性,它能够快速扩展并形成自己的服务,而无需正式的类,同时仍然允许轻松过渡到类结构。因此,上面的内容大致相当于

public class DB extends Popple
{
  public function Connect()
  {
    if(!isset($this['username']))
  	{
			die('Username required!');
		}
		echo 'Connecting as ' . $this['username'];
  }
}

$popple->Share('db', function($p)
{
  return new DB();
});

然后,你只需修改服务以更改它

$popple->Mutate('db', function($db)
{
  $oldconnect = $db->Connect;
	$db->Extend('Connect', function() use ($oldconnect)
	{
		$oldconnect();
		if(!isset($this['password']))
		{
			die('Password required!');
		}
		echo ' with password ' . $this['password'];
	});
	return $db;
});

然后,要使用新的 Connect 方法,你只需要做

$popple['db']['username'] = 'admin';
$popple['db']['password'] = 'password';
$popple['db']->Connect();

请注意,修改可以在任何时间点发生。服务可能已经实例化,可能已经注册,修改在实例化时排队,或者服务可能甚至尚未注册。无论怎样,它都会正常工作。这对于相互修改的服务非常有用。只需在另一个服务上注册修改,并让一切正常工作。你甚至可以为从未添加的服务注册修改而不会产生任何不良影响。

Popple 的最后一个附加功能是它可以被“弹出”,这就是其名称的由来。

弹出 Popple 将导致所有共享服务被实例化,并且这种实例化会沿着树向下执行,依次弹出任何额外的 Popple 或任何实现了 Poppable 的东西。

这似乎有些反直觉,因为这种系统的一个优势是尽可能延迟或防止实例化,但某些用例在加载时有一定的灵活性,通过预加载所有服务,可以在处理请求时最小化加载。