Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Slim framework: Currying vs Dependency Injection

In some frameworks like Angular, you can inject services and controllers into one other like this

App.controller('exampleController', function($scope, ajaxService){

    ajaxService.getData().then(function(data) {

        //do something with the data

    });

});

This is called Dependency Injection according to Angular docs

You can do something like this in Slim Framwork too, like this

$app->get('/example', function() use ($app, $db) {

    $data = $db->getData();

    //do something with the data

}

This is called Currying according to Slim docs.

As far as I see these are the exact same thing? Why are they called by different names?

like image 422
fairport Avatar asked Dec 14 '14 16:12

fairport


1 Answers

Couple of interesting reading here: What is currying What is dependency injection

No matter the programming language or framework, we could say "Dependency Injection" (DI) is something like delegation at OOP Class definition (see example) and Currying is something totally different, let's say function parameter simplification.

DI allows you keep your classes simple and de-coupled. If you are familiar with Laravel, ServiceProvider are a good example. In a nutshell your class has a property which will be set to a instance of another Class (normally implementing an interface) so that you can delegate some functionality. Typical example is:

interface LogInterface {
   public function write();
}

class LogToFile implements LogInterface {
   public function write()
   {
       //Do something
   }
}

class LogToFileDB implements LogInterface {
   public function write()
   {
       //Do something
   }
}

class MyDIClass {
   private $log;

   public function __construct(LogInterface $log){
       $this->log = $log;
   }

  public function writeLog(){
       $this->log->write();
   }
}

//You can do
$myobj = new MyDIClass(new LogToFile);
//or you can do 
//$myobj = new MyDIClass(new LogToDB);

//this will work, no worries about "write()" you are delegating through DI
$myobj->writeLog();

I've just written this code above (probably not functional) to illustrate DI. Using the interface you ensure the method "write()" will be implemented in any class implementing LogInterface. Then your class forces to get a LogInterface object when objects are instantiated. Forget how "write()" works, it is not your business.

In regards Currying, technique is diferent you just simplify the params in a function. When using Slim Framework the guys says "you can curry your routes by using $app". I've used Slim a lot and my understanding in that way is, ok, rathaer than pass several variables to your route closures just enrich your $app variable and pass 1 single var: $app

$app = new \Slim\Slim();
//Rather than 
//$app->get('/foo', function () use ($app, $log, $store, ...) {

$app->get('/foo', function () use ($app) {
    $app->render('foo.php'); // <-- SUCCESS
    $app->log->write();
    $app->db->store();
});
like image 170
jhmilan Avatar answered Nov 02 '22 13:11

jhmilan