Dependency Injection in drupal 8

Understanding php dependency injection with example will solve the purpose of drupal 8 DI

So Lets starts with classic example

Say If we defining a Database class and retrieving data from it  using oops

<?php

Class DataBase {

	public $database;

	public function __construct() {
	  $this->database = new MysqlDatabase();
	}

	public function getsomedata() {
	  $this->database->getdata();
	}

}

Class MysqlDatabase {
	public function __construct() {
	  // Code to connect to mysql database
	}

	public function getdata() {
	  // Code to retrive from mysql database
	}
}

$database = new DataBase();
$database->getsomedata();


This would connect to mysql database get some data from mysql.

So now the case is we want to access data from Oracle database

Class DataBase {

	public $database;

	public function __construct() {
	  $this->database = new Oracle();
	}

	public function getsomedata() {
	  $this->database->getdata();
	}

}

Class Oracle {
	public function __construct() {
	  // write Code to connect to oracle database
	}

	public function getdata() {
	  // write Code to retrive from oracle database
	}
}

$database = new DataBase();
$database->getsomedata();

Now Did You notice We need to change the Database class for each type of database We use. (for oracle and mysql) 

Now the case is We need to access data from generic database class without depending on database type and with out touching the main database class.

It should be generic and one time code and reusable.

Here now dependency Injection comes in Place with small change.

Class DataBase {

	public $database;

	
	public function __construct($database) { //Depency Injection
	  $this->database = $database;
	}

	public function getsomedata() {
	  $this->database->getdata();
	}

}


Class MysqlDatabase {
	public function __construct() {
	  // write Code to connect to mysql database
	}

	public function getdata() {
	  // write some Code to retrive from mysqldatabase
	}
}

Class Oracle {
	public function __construct() {
	  // write Code to connect to oracle database
	}

	public function getdata() {
	  // write Code to retrive from oracle database
	}
}

Class MongoDb {
	public function __construct() {
	  // write Code to connect to mongo database
	}

	public function getdata() {
	  // write Code to retrive from mongo database
	}
}

//for mysql 

$mysql = new MysqlDatabase();

$database = new DataBase($mysql);

$database->getsomedata(); //got mysql data without changing main database class

//for Oracle 

$oracle = new Oracle();

$database = new DataBase($oracle);

$database->getsomedata(); //got oracle data without changing main database class

//for Mongo 

$mongo = new MongoDb();

$database = new DataBase($mongo);

$database->getsomedata(); //got mongo data without changing main database class


Some Database type classes (Oracle, Mysql,Mongo ) may define their own member functions in their class without defining our functions that we are calling in our base database class, If they are defining the member functions as their wish or own functions,  then we will end up in trouble throwing fatal error, 

Say for example 

Class DataBase {

	public $database;

	
	public function __construct($database) { //Depency Injection
	  $this->database = $database;
	}

	public function getsomedata() {
	  $this->database->getdata(); // If this function is not there in mysql CLass fatal error
	}

}


Class MysqlDatabase {
	public function __construct() {
	  // write Code to connect to mysql database
	}

	public function IchangedTheGetDataFunctionToSomeOtherName() {
	  // write some Code to retrive from mysqldatabase
	}
}


So we need to restrict this happening, So we need to define some rules  that every databasetype classes should contain the functions that we are going to call in our main DataBase class.

this can be achieved by defining interface, let see how

// Our Rule defined with set of rule sets
// Rule is that every databasetype class comes in our base DataBase class, should be implemented our interface DatabaseInterface, This interface will make sure the member functions which we gonna call is implemented or defined in databasetype classes (ie) MongoDb,MysqlDatabase,Oracle.

interface DatabaseInterface {
 
 public function getdata();	
 public function insertdata();	
 public function updatedata();	
} 


Class DataBase {

	public $database;

    // Checking the rule that passed parameter object should be implemented with our  DatabaseInterface 

	public function __construct(DatabaseInterface  $database) {
	  $this->database = $database;
	}

	public function getsomedata() {
	  $this->database->getdata();
	}
    
    public function getinsertsomedata($data) {
	  $this->database->insertdata($data);
	}

	 public function getupdatesomedata($data, $conditions) {
	  $this->database->updatedata($data, $conditions);
	}

}


Class MysqlDatabase implements DatabaseInterface {
	public function __construct() {
	  // write Code to connect to mysql database
	}

	public function getdata() {
	  // write some Code to retrive from mysqldatabase
	}

	public function insertdata($data) {
	  // write Code to insert from mysql database
	}

	public function updatedata($data, $conditions) {
	  // write Code to update from mysql database
	}
}

Class Oracle implements DatabaseInterface {
	public function __construct() {
	  // write Code to connect to oracle database
	}

	public function getdata() {
	  // write Code to retrive from oracle database
	}

	public function insertdata($data) {
	  // write Code to insert from oracle database
	}

	public function updatedata($data, $conditions) {
	  // write Code to update from oracle database
	}
}

Class MongoDb implements DatabaseInterface {
	public function __construct() {
	  // write Code to connect to mongo database
	}

	public function getdata() {
	  // write Code to retrive from mongo database
	}

	public function insertdata($data) {
	  // write Code to insert from mongo database
	}

	public function updatedata($data, $conditions) {
	  // write Code to update from mongo database
	}
}


//for mysql 

$mysql = new MysqlDatabase();

$database = new DataBase($mysql);

$database->getsomedata(); //got mysql data without changing main database class
$database->getinsertsomedata($data);
$database->getupdatesomedata($data, $conditions);
//for Oracle 

$oracle = new Oracle();

$database = new DataBase($oracle);

$database->getsomedata(); //got oracle data without changing main database class
$database->getinsertsomedata($data);
$database->getupdatesomedata($data, $conditions);

//for Mongo 

$mongo = new MongoDb();

$database = new DataBase($mongo);

$database->getsomedata(); //got mongo data without changing main database class
$database->getinsertsomedata($data);
$database->getupdatesomedata($data, $conditions);

Thats it Hope You understand the purpose of dependency Injection and Usage :) Will See you with next article