In a new post to his blog, Loïc Frering is looking into integrating Symfony Dependency Injection Service with Zend Framework.
Dependency Injection is an Inversion of Control specific pattern highly used and encouraged throughout Zend Framework implementation. A Dependency Injection container manages your services life-cycle, it is in charge of their instantiation, configuration and injection as shared instances: no more need to use static methods, singletons or factories for your services!
Loïc is showing how to extend existing Zend Framework’s infrastructure to bootstrap Symfony’s Service Container, configure it and make services available through an action helper.
Singletons are often compared to same class of evil as goto instruction, or more familiar for PHP developers $GLOBALS. This thesis is hard to understand since Singleton is most basic and commonly know pattern. Even if one agrees with arguments, might find hard to eliminate singletons from own code. Giorgio Sironi shows that eliminating singletons is not that hard.
It is actually very simple to eliminate singletons: just force the components to ask for what they need in the constructor or via setters or via inject*() methods, instead of looking up a singleton trough a static method only to obtain a reference. Once this fundamental decoupling is achieved, the hard part is tackling the construction problem: Zend Framework has a big codebase and writing a factory (manual dependency injection) for every use case is not viable. Thus, automatic dependency injection needs to be called upon. There are many xml-configured dependency injection frameworks for php to incorporate, but let’s show a simple example of how they works.
The tutorial was split into two parts. First one presents basic solution for the problem. Second part addresses some problems related to objects having shorter lifetime than application-wide ones.
Testing application based on Zend Framework is generally smooth and easy, especially with help of Zend_Test component. Generally, but not always. Testing plugins or other extensions of some Zend Framework components can be tricky. One of such components is Zend_View and it’s helpers.
The empty constructor is the problem in view helper management, since it gets in the way of simple test code when you write view helpers that make use of other view helpers as collaborators. (…) In this design, the view acts as a Service Locator, and we have no idea which helpers could be called by another one: every helper class could depend on everything else. (…) My very-simple-testing solution would be require helpers to specify their collaborators in the constructor or via setters, implementing Dependency Injection. We cannot change the standard Zend Framework architecture, though, but it’s not a framework’s fault. This solution would have required to build a small automatic dependency injection system, which is not in the scope of Zend Framework 1.x (but will be in 2.x as far as I know).
Tricky and problematic does not mean impossible. In his latest post Giorgio Sironi presents his approach to unit testing Zend_View helpers. He explains problem of unit testing view helpers, proposes few solutions and presents the best one for him.