Search code examples
phplaravelinversion-of-control

Bind interface to implementation after login in Laravel


I need to perform one Interface to implementation binding after the user logs into the application. While logging in user selects an environment and based on which the binding needs to be performed. I have added the following binding to AppServiceProvider, but seems like this is booted before the login is performed.

$providerClass  = 'App\Models\\' . ucfirst($provider);

        $this->app->bind(
            'App\Repositories\MyRepository',
            $providerClass
        );

Is it possible to bind this from controller or what will be an alternate method to bind the interface to corresponding implementation based on the environment selected by the user ?


Solution

  • As @PtrTon said although it's a creative idea this is a bad idea. You can consider the laravel register pattern here.

    Registry Class:

    class EnvironmentGatewayRegistry {
    
      protected $gateways = [];
    
      function register ($name, EnvironmentGateway $instance) {
        $this->gateways[$name] = $instance;
        return $this;
      }
    
      function get($name) {
        if (in_array($name, $this->gateways)) {
          return $this->gateways[$name];
        } else {
          throw new Exception("Invalid gateway");
        }
      }
    
    }
    

    Your service provider

    $this->app->singleton(EnvironmentGatewayRegistry::class);
    
    $this->app->make(EnvironmentGatewayRegistry::class)
          ->register("dev", new DevImplemetaionClass())
          ->register("prod", new ProdImplemetaionClass());
    

    In your controller/anywhere you want you can inject the class EnvironmentGatewayRegistry and call get method with register name like dev, prod as a parameter.

    For more reference please check this document http://rizqi.id/laravel-registry-pattern