HiveBrain v1.2.0
Get Started
← Back to all entries
patternphpMinor

Is this a sensible way of using an IoC container?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thisioccontainerwaysensibleusing

Problem

I have a Factory class for a queuing system I'm playing around with.

Consuming classes only care that they get a particular interface (Job) as a result of calling the factory's load method.

Some Jobs may require a database connection, so I want to inject a PDO instance. Others may require something else, and I don't want to give all Jobs a PDO instance regardless of whether they need it.

This is what I've ended up with:

IoC class:

use Queue\Job\MeterData;
use PDO;

class IoC
{

    const DATABASE = 'db';

    const METER_DATA_JOB = 'job_meterData';

    public function get($item)
    {
        switch ($item) {

            case self::DATABASE:
                return new PDO('');

            case self::METER_DATA_JOB:
                return new MeterData($this->get(self::DATABASE));

        }
    }

}


Resulting Queue Factory class:

namespace Queue\Job;

use IoC;

class Factory
{

    const METER_DATA = 'meter-data';

    private $ioc;

    public function __construct(IoC $ioc)
    {
       $this->ioc = $ioc;
    }

    public function load($job)
    {
        switch ($job) {

            case self::METER_DATA:
                return $this->ioc->get(IoC::METER_DATA_JOB);

            default:
                throw new \Exception('No job class found for ' . $job);

        }
    }

}


In my mind having the Factory isn't strictly necessary but is advantageous, as I can doc-comment the load method and it will ensure that consuming code knows what type of object it is dealing with. It'll also keep all queue jobs together neatly, rather than having the consuming code access the IoC container directly instead of the more specific Queue Factory.

The problem is, if we assume that IoC container is going to be one class for a full application, isn't it going to get very messy very quickly, with a ton of import statements and such?

Is that really such an issue, because at least it will be limited to just the IoC container and it will keep the rest of

Solution

No. What you are doing is called The Service Locator Antipattern. And it's a bad thing.

The basic rule of thumb: Don't inject the container!.

The IoC container is supposed to be some sort of overseer, wiring your objects together at the bootstrap and configuration level. It isn't an object that's supposed to be injected into other objects, to create objects there.

Context

StackExchange Code Review Q#41587, answer score: 8

Revisions (0)

No revisions yet.