mardi 5 juin 2018

How to provide multiple implementations for a class in Laravel?

We are using some geocoding to encode a few entries. Depending on some conditions we would like to switch from an implementation to another (different provider).

Current service provider declaration:

// some skipped and irrelevant imports

class GeocoderServiceProvider extends ServiceProvider {

    public function register() {
        $this->app->singleton(GoogleMaps::class, function($app) {
            $adapter = $app->make(Client::class);
            $regionBiaising = 'US';
            $apiKey = $app['config']->get('services.googleGeocoding.apiKey');
            return new GoogleMaps($adapter, $regionBiaising, $apiKey);
        });

        $this->app->singleton(Geocoder::class, function($app) {
            $provider = $app->make(GoogleMaps::class);
            return new StatefulGeocoder($provider, 'en');
        });
    }

}

Current injection:

class SomeClientClass {

    /**
     * @var Geocoder
     */
    private $geocoder;

    public function __construct(Geocoder $geocoder) {
        $this->_geocoder = $geocoder;
    }

    // some code doing useful things

}

The target is to achieve something like this:

class SomeClientClass {

    /**
     * @var Geocoder
     */
    private $geocoder;

    public function __construct(Geocoder $geocoder, Whatever $alternativeGeocoder) {
        $this->_geocoder = ($condition) ? $geocoder : $alternativeGeocoder;
    }

    // some code doing useful things

}

I have tried to hack my way through it by making a fake subclass for my alternative Geocoder, unfortunately Geocoder\StatefulGeocoder is final. So this is not a solution.



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire