ZF2 – Dependency Injection

When using the service locator, you’ll find that interface injections are a common pattern applied.  The setup is simple, in your class you simply implement the existing interface injector:

namespace MyCacheService;

use ZendServiceManagerServiceLocatorAwareInterface,
    ZendServiceManagerServiceLocatorAwareTrait,
    MyCacheFlyWeightCacheAwareInterface,
    MyCacheFlyWeightCacheAwareTrait;

/**
 * Default strategy used to determine of an HTTP request can be cached
 */
class ExampleCanCacheStrategy extends DefaultCanCacheStrategy implements ServiceLocatorAwareInterface, FlyWeightCacheAwareInterface
{
    use ServiceLocatorAwareTrait, FlyWeightCacheAwareTrait;

    public function canCacheRequest(RequestInterface $request)
    {
        {...} // other code etc.
        $settings  = $this->getServiceLocator()->get('config');
        $path      = $request->getPath();
        $cacheable = $this->getFlyweightCache()->{function($path, $settings){
            foreach ($settings as $cacheableService) {
                if (preg_match('/' . $cacheableService['servicePath'] . '/', $path) === 1) {
                    return (bool) $cacheableService['cacheable'];
                }
            }
            return true;           
        }}($path, $settings);
        return $cacheable;
    }
}

I’ve used a trait to add in the additional interface requirements:

namespace MyCache;
use ZendCachePatternAbstractPattern;
trait FlyWeightCacheAwareTrait
{
    /**
     * @var AbstractPattern
     */
    protected $flyweightCache;

    /**
     * Sets the CacheAdapter for use within this interface
     * @param CacheAdapter $cacheAdapter
     */
    public function setFlyWeightCache(AbstractPattern $cachePattern)
    {
        $this->flyweightCache = $cachePattern;
    }

    /**
     * returns the cache adapter to the user.
     * @return CacheAdapter The current CacheAdapter
     */
    public function getFlyWeightCache()
    {
        return $this->flyweightCache;
    }
}

The interface is below:

namespace MyCache;
use ZendCachePatternAbstractPattern;
interface FlyWeightCacheAwareInterface
{
    /**
     * Sets the CacheAdapter for use within this interface
     * @param CacheAdapter $cacheAdapter
     */
    public function setFlyWeightCache(AbstractPattern $cachePattern);

    /**
     * returns the cache adapter to the user.
     * @return CacheAdapter The current CacheAdapter
     */
    public function getFlyWeightCache();
}

Once this is implemented you can create your dependencies and inject them into the instance that’s been created, or you can use the initializer injection system that’s automatically run when you generate an instance using the service locator.

namespace MyCache;

use ZendServiceManagerInitializerInterface,
    ZendServiceManagerServiceLocatorInterface,
    MyCacheFlyWeightCacheAwareInterface;

class CacheAwareInitializer implements InitializerInterface {
    public function initialize($instance, ServiceLocatorInterface $serviceLocator)
    {
        // HACK for View, Controller, AND Service!
        $sm = (method_exists($serviceLocator, 'getServiceLocator')) ? $serviceLocator->getServiceLocator() : $serviceLocator;
        {...} // Additional injection code

        if ($instance instanceof FlyWeightCacheAwareInterface) {
            $callbackCache = ZendCachePatternFactory::factory('callback', array('storage' => $sm->get('callbackCache')));
            $instance->setFlyWeightCache($callbackCache);
        }
    }
}

Any time you try to get an instance using the service locator, this function will run, and inject your dependency directly into your instance.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s