Welcome Guest, Not a member yet? Register   Sign In
User configurable controller factory
#1

This is related to DI (dependency injection) but I want to make it clear up front that I am not just talking about DI i.e. this is not a duplicate of https://forum.codeigniter.com/thread-61345.html et al.

This is a subtly different feature request as implementing a user-configurable controller factory would permit end-users to implement DI differently if they wanted to do so.

In CodeIgniter\CodeIgniter::createController() (framework/system/CodeIgniter.php) controllers are instantiated with the new keyword. If this was extracted to a factory class (perhaps resolvable via the Services configuration file) then end-users would be able to manage dependency injection for their controllers.

A quick example implementation:

PHP Code:
  /**
     * In app/Config/Services.php
     * @param string $requestedName
     * @return object
     */
    public static function controllerFactory($requestedName)
    {
        return new $requestedName;
    

With CodeIgniter\CodeIgniter::createController() altered to call this user-configurable factory:

PHP Code:
    /**
     * Instantiates the controller class.
     *
     * @return mixed
     */
    
protected function createController()
    {
        
$class Services::controllerFactory($this->controller);
        
$class->initController($this->request$this->responseServices::logger());

        
$this->benchmark->stop('controller_constructor');

        return 
$class;
    } 

So far this would work exactly the same as the current controller instantiation but the instantiation has been moved into user space allowing end-users to instantiate controllers differently. An alternative implementation of the controllerFactory service might look like this:


PHP Code:
    /**
     * In app/Config/Services.php
     * @param string $requestedName
     * @return object
     */
    
public static function controllerFactory($requestedName)
    {
     
   if(is_subclass_of($requestedName, \App\Controllers\CustomBaseController::class)) {
     
       return new $requestedName(static::getSharedInstance('example'));
     
   }

     
   return new $requestedName;
    } 

Or it could be quite different. The point being that it is user-configurable. Thoughts?
Reply
#2

I'll be honest - I'm a little fuzzy on what people would use it for, but I'm all for it. send in a PR.
Reply
#3

What people could use it for: at present it seems that CI4 only supports service location in a base controller class, which is fine but many people prefer to inject dependencies via the constructor. Moving the controller class instantiation into user space allows end-users to write factory classes or factory methods (located in, for example, app/Config/Services.php), allowing them to implement dependency injection as they see fit.

Thank you for being receptive and for the suggestion of sending a PR, I will likely to do so.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB