1

Original Class

class HomeController
{
    function __construct()
    {
        $this->setPhpRenderer('Module');
        $this->repository = new HomeRepository($id);
        $this->proposalService = new ProposalService($this->repository);
        $this->quickAdd = new QuickAdd($this->repository);
    }
}

/*
 * Instantiation is nice and clean:
 */
$home = new HomeController();

Using Dependency Injection

class HomeController
{
    function __construct(
        PhpRenderer $renderer,
        HomeRepository $repository,
        ProposalService $proposalService,
        QuickAdd $quickAdd)
    )
    {
        $this->renderer = $renderer;
        $this->repository = $repository;
        $this->proposalService = $proposalService;
        $this->quickAdd = quickAdd;
    }
}

/*
 * Instantiate Class components
 */    
$renderer = PhpRenderer('Module');
$repository = new HomeRepository($id);
$proposalService = new ProposalService($this->repository);
$quickAdd = new QuickAdd($this->repository);

/*
 * Instantiate class - 
 */
$home = new HomeController(
            $renderer, 
            $repository,
            $proposalService, 
            $quickAdd
        );

Question

I am noting that DI adds a boatloads of code and I want to keep my instantiation nice and neat while still using dependency injection principles.

One thought I've had is instead of passing individual class components, put those components into an array. This will add extra code of course to manage the array, but all class components will be tucked into it.

  • 2
    That's the price you pay for an additional level of indirection. Have you considered using a DI framework? – Robert Harvey Oct 13 '16 at 16:56
  • thanks, can you say more on what level of indirection means in this case? Do you mean abstraction? I'm not quite sure what those mean. – Dennis Oct 13 '16 at 16:58
  • Yes, same thing. – Robert Harvey Oct 13 '16 at 16:59
  • 1
    Every computing technique has a cost. You have to evaluate that cost against the benefits the technique provides. – Robert Harvey Oct 13 '16 at 16:59
  • I haven't looked into DI frameworks. I plan to use more features of Zend Framework, but have not used dependency injection containers or such just yet. – Dennis Oct 13 '16 at 17:01
3

You can use IoC containers to do that. You just dump all of the dependencies in them (or let the IoC container discover them).

I do not recommend this route as it complicates debugging, complicates unit testing, and otherwise obfuscates what's going on when you're just looking to make things cleaner (and thus more readable).

You could use basic factories, which takes the injection and hides it behind a factory call.

I generally do not recommend this route as it's added boilerplate to what you already have and more things to screw up. And it also tends to make your code less discoverable.

But in general - you should not do either. Those few added lines aren't that much noise. They make it explicit what is going on. They add flexibility for how people can use your code. They make it easier to debug the code. They make the code better.

  • thanks. While certainly Factories do add extra code, I don't think they necessarily hide things too badly. They essentially hide all the prep work and initialization that I have in my 2nd example. I may be biased based on my familiarity of Zend Framework (where I have used Factories for such things and which has facilities to accommodate them). – Dennis Oct 13 '16 at 17:06
0

The best technique to resolve this is to choose convention over configuration.

Containers can end up hiding dependencies in a mysterious way. Factories can end up doing the same but don't have to.

The heart and soul of convention is default values. The trick is you need to allow every default to be overridden independently. If your language allows named parameters you get this for free. If not you need construction code that simulates it.

In java the go to pattern for this is the josh builder. There is a PHP variation.

Honestly, the josh builder style only leads to less code than what you started with here when you have more code that builds objects than you have code that defines objects.

Your style makes defining a class easy but building it a pain. The Bloch builder makes defining a class a pain but building easy.

They both offer flexibility so it's what you do most that determines what makes most sense.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.