Laravel IoC - am I doing this right?

207 views Asked by At

I am trying to learn the concepts of IoC by using Laravel service providers. What I've read so far, you should contain all your class creation logic that is dependent on other classes within service providers. Fair and square, but I want to make sure I'm doing it the right way.

My application will make use of children of the abstract Tracker class, depending on what constant you provide to the service provider, it should load a different class. Is this the right way to go?

The Service Provider:

class TrackerServiceProvider extends \Illuminate\Support\ServiceProvider {
    const TRACKER_API  = 0;
    const TRACKER_SITE = 1;

    public function register() {
        $this->app->bind('Tracker', function($app, $parameters) {
            switch($parameters['method']) {
                case static::TRACKER_API:
                    return new TrackerAPI(new cURL(),  new Shipment($parameters['number']));

                    break;
                case static::TRACKER_SITE:
                    return new TrackerSite(new cURL(), new Shipment($parameters['number']));

                    break;
                default:
                    throw Exception('Unknown tracker method provided.');

                    break;
            }
        });
    }
}

The abstract Tracker class (just the base):

abstract class Tracker {
    protected $curl;
    protected $shipment;


    function __construct(cURL $curl, Shipment $shipment) {
        $this->curl     = $curl;
        $this->shipment = $shipment;



    }
}

Or should I create two different bindings in the register method, one for each class? Like this:

class TrackerServiceProvider extends \Illuminate\Support\ServiceProvider {
    public function register() {
        $this->app->bind('TrackerAPI', function($app, $number) {
             return new TrackerAPI(new cURL(),  new Shipment($number));
        });

        $this->app->bind('TrackerSite', function($app, $parameters) {
             return new TrackerSite(new cURL(),  new Shipment($number));
        });
    }
}
1

There are 1 answers

0
Pete Houston On

I prefer to make a Factory here to decoupling it from the ServiceProvider. Following code is just a demonstration, better not to use the static method in the below TrackerFactory.

class TrackerFactory {
    const TRACKER_API  = 0;
    const TRACKER_SITE = 1;

    public static function make($parameters) {
        switch($parameters['method']) {
            case static::TRACKER_API:
                return new TrackerAPI(new cURL(),  new Shipment($parameters['number']));

                break;
            case static::TRACKER_SITE:
                return new TrackerSite(new cURL(), new Shipment($parameters['number']));

                break;
            default:
                throw Exception('Unknown tracker method provided.');

                break;
        }
    }
}

then just bind it.

class TrackerServiceProvider extends \Illuminate\Support\ServiceProvider {

    public function register() {
        $this->app->bind('Tracker', function($app, $parameters) {
            return TrackerFactory::make($parameters)
        });
    }
}