Posts by Tag "DependencyInjection"

Subscribe to posts of this tag

Using Symfony Dependency Injection with Zend_Application

As a follow-up to my recent post on Dependency Injection containers and Zend_Application I was eager to find out if its possible to integrate the new Symfony Dependency Injection Container into the Zend Framework. To my suprise its possible without having to make any changes to one of the two components. An example use-case would look like:

$container = new sfServiceContainerBuilder();
 
$loader = new sfServiceContainerLoaderFileXml($container);
$loader->load(APPLICATION_PATH.'/config/objects.xml');
 
$application = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH . '/config/application.xml'
);
$application->getBootstrap()->setContainer($container);
$application->bootstrap()
            ->run();

Resources instantiated by Zend_Application are then injected into the container by the name of the resource and are given the resource instance. Any object from the Symfony container can then use these dependencies in their object setup. The only drawback of the integration is the fact that the Symfony Container is case-sensitive in regards to the service names but Zend_Application lower-cases all service before injecting them into the container. The following code is a restatement of my previous example of a MyModel class which requires a Zend_Db and Zend_Cache constructor argument.

$container->register('myModel', 'MyModel')
          ->addArgument(new sfServiceReference('db'))
          ->addArgument(new sfServiceReference('cache'));

Access to a MyModel instance with its dependencies is then granted through the call $container->myModel throughout the application. Make sure to call this after running Zend_Application::bootstrap, so that the Resource dependencies are injected first.

Using a Dependency Injection Container with Zend_Application

Much has been written on Dependency Injection lately, mostly by Padraic Brady (1, 2) and Fabien Potencier (1, 2, 3, 4, 5). My subjective feeling tells me there are now more PHP DI containers out there than CMS or ORMs implemented in PHP, including two written by myself (an overengineered and a useful one). Its an awesome pattern if used on a larger scale and can (re-) wire a complex business application according to a clients needs without having to change much of the domain code. It aims at a complete seperation of object instantiation and dependency tracking from the business logic.

Beginning with version 1.8 Zend Framework is able to integrate any of these DI containers into its Zend_Application component easily. The Application component intializes a set of common resources and pushes them into the MVC stack as additional Front Controller parameters. Technically a Zend_Registry instance holds all these resources with their respective resource names as keys. The resources are accessible inside the Front Controller and the Action Controller classes. Assume the resource 'Db' is initialized in your application, you can access it with:

$front = Zend_Controller_Front::getInstance();
$container = $front->getParam('bootstrap')->getContainer();
$db = $container->db;
 
// or:
class FooController extends Zend_Controller_Action {
    public function barAction()
    {
        $container = $this->getInvokeArg('bootstrap')->getContainer();
        $db = $container->db;
    }
}

This is pretty much dependency injection already, but the default registry approach suffers from two serious problem: New instances can only be added to the Container by implementing new Zend_Application resources and these instances cannot be lazy loaded. All resources used by Zend_Application are always loaded on every request. But the application container implementation was developed with Dependency Injection in mind and is not tied to the use of Zend_Registry. Only three magic methods are required by any container that wants to be Zend_Application compliant: __get(), __set() and __isset(). Each instantiated resource is pushed via __set() into the container. If required by another resource, __isset() is used to check wheater a resource with the given name exists inside the container and __get() is used to retrieve the instances from the container.

Some month ago I extended Yadif, a lightweight PicoContainer-like DI container for PHP written by Thomas McKelvey, with several features that make it a very powerful DI container in my opinion. It has a detailed documentation and examples on the GitHub Page if you want to check it out. I extended Yadif to be Zend_Application compliant in a way that the application-wide Zend_Application resources can be used as dependencies for objects that are lazy-loaded from the container. Skipping the tech-talk, here is an example. First we have to replace the default Container with Yadif:

$objects = new Zend_Config_Xml(APPLICATION_PATH."/config/objects.xml");
$container = new Yadif_Container($objects);
 
$application = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH . '/config/application.xml'
);
// Set Yadif as Container
$application->getBootstrap()->setContainer($container);
$application->bootstrap()
            ->run();

Assume you run Zend_Application with a "Db" and a "Cache" resource. These resources are loaded on every request. The objects configured in Yadif however are not instantiated until they are requested for the first time from the container. We can merge these two worlds and make use of the Application resources inside the Yadif Configuration "objects.xml", which looks like:

<?xml version="1.0" ?>
<objects>
    <myModel>
        <class>MyModel</class>
        <arguments arg1="db" arg2="cache" />
    </myModel>
</objects>

Instantiating a myModel class inside the Action Controller uses the the Database and Cache resources as constructor arguments:

class FooController extends Zend_Controller_Action {
    public function barAction()
    {
        $container = $this->getInvokeArg('bootstrap')->getContainer();
        $myModel = $container->myModel;
    }
}

Given the possibilites by the Yadif_Container you are now empowered to use Dependency Injection for all your application objects and make use of Zend_Applications resource system. Furthermore any other dependency injection container, simple or complex, can also be integrated easily.

Dependency Injection with PHP: Introducing Sphicy

I have written on dependency injection before christmas and how Guice, googles DI framework, offers a simple solution. I copied the functionality for a PHP clone of Guice and named it Sphicy. You saw an early prototype of it in the blogpost mentioned above.

Sphicy configures object dependencies with modules: You explicitly state which implementation should be bound to which interface. An injector then creates instances of these objects via reflection: All constructor dependencies are resolved by looking at the given type hints and initializes those according to the specified bindings.

Two examples included in the source code of Sphicy are Zend Framework and ezComponents MVC bootstrapping modules. Sadly both frameworks default front controllers are engineered in such a way that useful dependency injection needs some workarounds.

As an example I will now discuss the Sphicy Module for Zend Framework MVC applications. To circumvent the singleton and protected Constructor of Zend_Controller_Front, we have to build a new front controller that wraps around it and requires all the dependencies:

class Sphicy_Controller_Front
{
    protected $front;
 
    /**
     * Create Front Controller for Zend Framework using explicity dependencies created by Sphicy.
     *
     * @param Zend_Controller_Request_Abstract      $request
     * @param Zend_Controller_Response_Abstract     $response
     * @param Zend_Controller_Router_Interface      $router
     * @param Zend_Controller_Dispatcher_Interface  $dispatcher
     */
    public function __construct(
        Zend_Controller_Request_Abstract $request,
        Zend_Controller_Response_Abstract $response,
        Zend_Controller_Router_Interface $router,
        Zend_Controller_Dispatcher_Interface $dispatcher=null
    )
    {
        $front = Zend_Controller_Front::getInstance();
        $front->setRequest($request);
        $front->setResponse($response);
        $front->setRouter($router);
 
        if($dispatcher === null) {
            $dispatcher = $front->getDispatcher();
        }
        $front->setDispatcher($dispatcher);
    }
 
    public function dispatch()
    {
        $this->front->dispatch();
    }
}

You can see that the Sphicy_Controller_Front class requires dependencies in its constructor that are then forward injected into Zend_Controller_Front. You can now create a module that binds all the required dependencies to concrete implementations, for example a module for a Zend MVC Http Application might look like:

class Sphicy_ZendMvc_ExampleModule implements spModule {
     public function configure(spBinder $binder) {
         // Sphicy_Controller_Front does not extend Zend_Controller_Front, because of Singletonitis
         // It offers the dispatch method to proxy against Zend_Controller_Front::dispatch.
         $binder->bind("Sphicy_Controller_Front")->to("Sphicy_Controller_Front");
         $binder->bind("Zend_Controller_Request_Abstract")->to("Zend_Controller_Request_Http");
         $binder->bind("Zend_Controller_Response_Abstract")->to("Zend_Controller_Response_Http");
         // loads all routes
         $binder->bind("Zend_Controller_Router_Interface")->to("MyApplication_Router");
     }
 }

The class MyApplication_Router might look up all the routing information of the application via a hardcoded configuration mechanism. You may say this is a hard dependency, but actually you can just switch modules or implementations at this position to replace the router with another implementation. You can also see that no implementation for the dispatcher is bound. But this dependency is optional and will be created automatically as can be seen in the Sphicy_Controller_Front class.

The front controllers is now created by calling:

$injector = new spDefaultInjector(new Sphicy_ZendMvc_ExampleModule());
$front = $injector->getInstance("Sphicy_Controller_Front");
$front->dispatch();

What happens in the $injector->getInstance() line? Sphicy looks at Sphicy_Controller_Front's constructor and finds that four dependencies are needed: Request, Response, Router and Dispatcher implementations. It looks up the bindings and searches for them, creating Zend_Controller_Request_Http, Zend_Controller_Response_Http and MyApplication_Router objects. A dispatcher implementation is not found, but Sphicy recognizes that null is a valid paramater and injects it. The 3 concrete implementations and one null are instantiated and used to construct a valid Sphicy_Controller_Front instance.

You have now stated the dependencies of the Zend Controller Front explicitly and can switch them instantaneously by switching the bindings of interface to implementations in the configuration module.

Have a look at the Sphicy Website and FAQ to see more examples and information about the possibilites of this dependency injection framework.

Dependecy Injection the juicy way

I have written on dependency injection before and came up with a solution for PHP via interface injection. Thinking about it twice I didn't like it very much. Its too much overkill that you have to implement all setter methods again and again.

Still dependency injection is the way to write good, testable and easily exchanged and re-wired object graphs. I tried to do lots of dependency injection via constructor lately and realized that it polutes my constructors when my object graph is too deep.

An example: When I setup my database connection in the bootstrap file and encapsulate it in my model creation factory object, i have to insert the model factory through the configuration into the dispatcher into the different controllers and views to be accessible in the MVC pattern. The model factory has to walk 3 nodes in the object graph without being used at all in the "higher" steps. This creates very unnecessary dependencies.

I came across Misko Hevery's Blog, which rocks. There are also some great Google Tech Talks by him, where he argues in favour of dependency injection and debunks singletons as being evil (he does that on his blog too). From there I learnt about Guice, a dependency injection framework for Java by Google.

What I like about Guice: Its easy to use and its immediatly obvious to someone without experience, why it works so good and you don't have to hand down objects deep down the object graph. I cloned the basic functionality for PHP and an example would work as follows.

We first have to implement a module, which defines which concrete implementation should be injected as a placeholder for which interface.

class ServiceModule implements Module{ public function configure(Binder $b) {  $b->bind("Service")->to("ConcreteService");  $b->bind("Add")->to("ConcreteAdd");  $b->bind("Sub")->to("ConcreteSub"); }}

We can now use this module to instantiate an injector object:

$injector = new Injector( new ServiceModule() );$service = $injector->getInstance("Service");

Given that the constructor of ConcreteService would expect an Add and a Sub object, the Injector would realize this and instantiate the concrete implementations ConcreteAdd and ConcreteSub and inject them into the constructor.

What makes this dependency injection so simple and great to use? You can instantiate an injector everywhere in your code and just have to configure it using the additional module implementation. This way you don't have to make sure that you pass down the dependency injection container from the bootstrap into all nodes of the application. You can also easily work with many frameworks and still be able to use dependency injection without having to hack the whole core of the framework.

My guice clone does more. It allows to pass down additional non-object arguments into constructors, even for object dependencies. It offers a Provider interface to be able to wrap adapters around your already existing ServiceLocator or Registry objects. But its reflection capabilities have to be extended to docblock comments, so that better dependency detection is possible.

Because using dependency injection with only this little example I will refrain from releasing the source code yet. I have to provide some useful documentation for it to be of use to anyone.

Dependency Injection via Interface in PHP: An example

Personal projects and work currently both force me to think about application design and I came accross dependency injection the other day. Its quite a complex Design Pattern and hard to grasp, even with the number of examples you can find in the internet. Basically Dependency Injection means you register components that might be a dependency for other components and when loading new classes via the dependency injection framework, it knows of this relationsships and assembles the object in need and all its dependencies and returns them fully initialized. This pattern leads to completly encapsulated objects where any class in the object graph can be exchanged for a new implementation without breaking all its dependencies. It also makes testing complex components and object relationsships very easy.

Asfar as I could find out, three different types of Dependency Injection implementations exist: Via Constructor, via Setter and via Interfaces. There exist implementations of Dependency Injection for Java (Spring) that are configured via XML config files and seem very complex. They are also hard to read in code I pressume, since you always have to be aware of the current application configuration. There are also some more lightweight implementations (PicoContainer) that assemble their relationsships in the application and work with config methods that act as configuration of the dependancies. Martin Folwer also discusses an implementation via interfaces, which seems most accessible for me.

All PHP clones of any dependancy injection framework seem to go the complex way via configuration though. With traits and multiple class inheritance on the horizon, some kind of interface injection seems mighty powerful though. So I implemented a really lightweight implementation of Interface Dependency Injection for PHP. The Container works with static method only, is therefore in the global scope, such that configuration is reduced to a minimum. Generally you have to write interfaces for object injection, for example:

interface InjectDbAdapter{  public function injectDbAdapter(Zend_Db_Adapter_Abstract $db);}

Other potential examples include "InjectLogger", "InjectSoapClient", or "InjectAppConfig". You then have to register a component for usage with this interface:

Whitewashing_Container::registerComponent('InjectDbAdapter', Zend_Db::factory($dbConfig));
Now any class that implements the InjectDbAdapter interface can be instantiated via:
$obj = Whitewashing_Container::load('Class');

and the loader takes care of calling the 'Class' implementation of injectDbAdapter with the given Database Adapter. A negative consequence of this approach is that you have to implement the inject methods for all interfaces in your concrete class implementations. With Traits (multiple class inheritence) being a new feature in PHP soon, injection via parent classes seems to become a very powerful approach though, which can handle the concrete implementations.

The Container takes care of all the dependancy building, so when testing your components you can register lots of mock objects. You can also exchange dependancies for only a subset of objects very easily. I implemented a method "Whitewashing_Container::registerClassComponent", which registers a dependency component that is used with higher priority in construction of the given class. You can also specify a third parameter $localInterfaceOverride for the highest priority:

$obj = Whitewashing_Container::load('Class', null, array('InjectDbAdapter' => $newDbAdapter));

Speedwise the usage of the Container reduces class instatiation by about 50%, from 0.5 sec for 10000 classes with setting dependencies to 1 sec on my machine. But naturally only classes with dependancies and lots of them should be using this mechanism and with good application design, this shouldn't be to many. You can download Container and Example sourcecode, to take a look. Currently this Container is not really creating new dependencies for each new class generation but rather inverts the usage of a registry. It should be an easy task to extend the registering method to decide between new class generation and using the globally registered class instance.