lundi 8 mai 2017

MVC: Share a service (or a domain object) between controller and view

I'm working on my (H)MVC project in which I separated the views from the controllers. So, no view rendering in a controller.

What I want to achieve: I try to share the same instance of a service between a controller and a view. User tereško has a very good presentation on this: How should a model be structured in MVC?. But I don't want to use a service factory (if possible).

The controller and the view, each, have the AuthenticationService as constructor parameter and an action authenticate().

class UsersController {

    private $authentication;

    public function __construct(AuthenticationService $authentication) {
        $this->authentication = $authentication;
    }

    public function authenticate($id = NULL) {
        // Update the state of the service.
    }

}

class UsersView {

    private $authentication;

    public function __construct(AuthenticationService $authentication) {
        $this->authentication = $authentication;
    }

    public function authenticate($id = NULL) {
        // Read the (state of) the service and display it on screen.
    }

}

In Bootstrap.php I'm creating the controller and the view and I'm calling their actions. I'm using a dependency injection container (Auryn).

// Action from route.
$actionName = 'authenticate';
$actionParameters = array(143);

// Fully qualified class names.
$viewFQN = 'MyMVC\Modules\Users\Views\UsersView';
$controllerFQN = 'MyMVC\Modules\Users\Controllers\UsersController';

// Inject dependencies through DIC.
$view = $injector->make($viewFQN);
$controller = $injector->make($controllerFQN);

// Call actions.
$controllerActionCalled = call_user_func_array(array($controller, $actionName), $actionParameters);
$viewActionCalled = call_user_func_array(array($view, $actionName), $actionParameters);

The problem: In Bootstrap.php I can not already know that the controller and the view take an AuthenticationService as argument. Therefore I can not instantiate AuthenticationService and share it with DIC, like this

$authentication = new AuthenticationService();
$injector->share($authentication);

But I need a mechanism to work on the same service instance, both in controller and view.

The service may also be just a domain object as part of the model layer.

Any suggestions, please? Thank you.

Aucun commentaire:

Enregistrer un commentaire