samedi 6 mai 2017

HMVC with dependency injection container: too many dependencies? No global state (!)

I'm working on a personal HMVC project. All project dependencies are resolved and created on bootstrap level through Auryn dependency injection container. No service locator. No global state, like static or global. No singletons. Controllers from other modules are instantiable through a controller factory. The model handling (domain objects, repositories, data mappers) is not yet encapsulated in services, but let's say I use now an Authentication service. I also use namespaces (as described in PSR-4: Autoloader).

All controllers extend an abstract controller. At this moment I inject all needed dependencies (actually, that I think I'll need) in the corresponding controller constructors. Example:

class Users extends AbstractController {

    private $authentification;

    public function __construct(
        Config $config // Shared through DIC
        , Request $request // Shared through DIC
        , Session $session // Shared through DIC
        , View $view // Module scope (all objects in a module become same instance)
        , Response $response // Module scope
        , ControllerFactory $controllerFactory
        , Logger $logger // Shared through DIC
        /* OTHER UTILS... */
        , Authentification $authentification // Model layer service(s).
    ) {
        parent::__construct(/* All parent dependencies */);
        $this->setAuthentification($authentification);
    }

    // With the action parameters passed by routing.
    public function authenticateUser($id) {
        //...
    }

}

So the dependencies list is big and would further grow. I'm aware that I need to change this, so I was thinking about:

  • To totally separate controllers from views. They would share the model layer. The views wouldn't belong to controllers anymore. And the Response would be a dependency of the views. But how would then work my ControllerFactory? Then I would also have to call a view action in addition of calling a controller action.
  • To use setter injection of Request, Session, Logger, etc. in the controllers, or to inject them in the controller actions (on-demand) after the action parameters like: public function authenticateUser($id, Request $request, Session $session){/*...*/}.
  • To use decorators. Like for Logger.
  • To implement some factories for the "utilities".

I would appreciate, if you would help me find an elegant way to deal with this task. I'm pretty sure that I miss something in respect of the perspective in which I look at it in my HMVC project and maybe at HMVC (without global state (!)) in general. Thank you.

Aucun commentaire:

Enregistrer un commentaire