2009年4月13日星期一

[fw-mvc] Proposed addition to Zend_Application API

Greets, all --

One thing I -- and others -- have been struggling with regarding
Zend_Application is how to share resources both during bootstrapping as
well as during the actual application runtime.

The easy way to do this is simply to define your resources such that
they add to the registry:

public function _initFoo()
{
$foo = new Foo();
Zend_Registry::set('Foo', $foo);
}

This is problematic on a few levels, though. Global registries are
difficult to test against, and introduce hard to track dependencies into
your code.

Another possibility is to introduce a DI Container into ZF. This is a
nice solution, and one I want to entertain -- but requires a lot of
thought and effort, and I don't want to hold up 1.8 for this.

Yet another possibility is to introduce a local registry. A little known
fact about Zend_Registry is that you can also create non-global
registries with it. This would allow us to push the registry into module
bootstraps as well as the front controller, which would allow you to
pull from it in your action controllers, helpers, and plugins.

The idea here would be that if a resource method or plugin has a
non-null return value, then that value would be registered with the
registry. As an example, let's look at a potential implementation of the
FrontController resource plugin:

class Zend_Application_Resource_Router extends Zend_Application_Resource_Base
{
public function init()
{
// Grab the registry from the bootstrap:
$registry = $this->getBootstrap()->getRegistry();

// Grab the front controller:
$front = $registry->frontcontroller;

// do some stuff, and initialize the router...
// add the router to the front controller:
$front->setRouter($router);

return $router;
}
}

Because the resource now has an explicit return value, the Bootstrap
would register it with the local registry. To keep things simple and
consistent, the key would match the resource. So, if you wanted to
retrieve the router, you'd use this:

$router = $registry->router;

In your action controllers, you'd use the following:

$registry = $this->getInvokeArg('registry');
$router = $registry->router;

This would be a simple change to make to the Zend_Application API, easy
to document, and not really affect BC with those who have been
experimenting with the 1.8 preview release.

Any thoughts?

--
Matthew Weier O'Phinney
Project Lead | matthew@zend.com
Zend Framework | http://framework.zend.com/

没有评论: