Slim DI Factories

Regarding adding dependency injection to controllers, or other classes for that matter, I’m curious if there’s any difference implementing them with either of these two options or if it just comes down to preference.

Option 1

$c = $app->getContainer();

$c['DBService'] = function() {
  return new DBService;
};

$c['Controller'] = function($c) {
  $dbService = $c->get('DBService');
  return new Controller($dbService);
};

Option 2

$dbService = new DBService;

$c = $app->getContainer();

$c['Controller'] = function($c) use ($dbService) {
  return new Controller($dbService);
};

With option 1, it seems as though it would be a bit cleaner to inject multiple classes if necessary rather than instantiating the class first, as in option two, and then adding them as parameters in the container.

With option 2 the DBService will be instantiated if it is needed or not. Probably not a big deal if all (or almost all) of your application needs it. But in general Option 1 is probably preferred because it leaves it up to the App to decide what it needs from the container and then only instantiate what is needed.

That makes sense. With that said, I think I might implement a global container to be used through the application and use modular containers as needed.

Something like this:

// file included app wide
$_global = $app->getContainer();

$_global['dbService'] = function() {
  return new DB\Service;
};

// app module
$c = $app->getContainer();

$c['userService'] = function() use ($_global) {
  $dbService = $_global->get('dbService');
  return new User\Service($dbService);
};

$c['toDoService'] = function() use ($_global) {
  $dbService = $_global->get('dbService');
  return new ToDo\Service($dbService);
};

$c['toDoController'] = function($c) {
  $userService = $c->get('userService');
  $toDoService = $c->get('toDoService');
  return new ToDo\Controller($userService,$toDoService);
};

I sort of do something similar, but put them into my index.php file, similar to how the database connection is defined here.

Thanks for the link. I’m going to take a look at it a little more in depth but at a glance it definitely looks like it falls in line with what I’m wanting to accomplish.