1

A lot of the time when working on legacy code bases, I find it hard to move manually created dependencies to the constructor parameters, because of a variety of reasons. Sometimes it's because the amount of refactoring needed is too significant at the time, or that object creation is already being handled by other means, which means hooking up the class to a container isn't feasible. An example of this is in a Joomla codebase I have inherited. There is a pervasive pattern of getting singletons from core Joomla static methods.

class FooController extends JControllerLegacy
{
    public function display($cachable = false, $urlparams = array())
    {
        $app = JFactory::getApplication();
        $input = $app->input;
        $input->set('view', 'foo');
        parent::display($cacheable, $urlparams);
    }
} 

I can't inject app, because the Joomla "framework" does some voodoo magic to instantiate controller methods based on class names. To get around this I enable dependency injection, but I make it optional, so that the code continues to function within it's current bounds.

class FooController extends JControllerLegacy
{
    private $app;

    public function __construct(JApplicationCms $app = null)
    {
         $app = $app ?: JFactory::getApplication();
         $this->app = $app;
    }

    public function display($cachable = false, $urlparams = array())
    {
        $input = $this->app->input;
        $input->set('view', 'foo');
        parent::display($cacheable, $urlparams);
    }
 }

IMO, this gets me the basic benefits of DI. I can mock out the JApplicationCms in a unit test, and dependencies are listed in a centralized place. The downside being that I'm still relying on the static method in most cases.

maxiscool
  • 111
  • 3

0 Answers0