Reputation: 249
So - I want to to switch my code to dependency injection, dependency injection container (DIC) paradigm. And I've been reading about it... it sorta seems to me that I've already been doing that all along... maybe...
What I was doing - I was creating namespaced class (container?), which I'd usually call Api, for each separate project which I'd then instantiate and fetch configured objects from. Actual example:
<?php
/**
* @namespace
*/
namespace SomeNamespace;
/**
* api
*/
class api {
public function __construct() {
/*
* Requiring all of the common files.
*/
require_once( VENDORS_PATH . DIRECTORY_SEPARATOR . 'PHPMailer' . DIRECTORY_SEPARATOR . 'class.phpmailer.php' );
require_once( VENDORS_PATH . DIRECTORY_SEPARATOR . 'PHPMailer' . DIRECTORY_SEPARATOR . 'class.smtp.php' );
}
private function getPostgresqlPreprocessor() {
$spp = new \SomeNamespace\Utils\PostgresSearchPreProcessor();
$settingsService = $this->getSettingsService();
$settings = $settingsService->readSettings();
$spp->setValidator( new \Auro\Validation\Validator() )
->setSettings( $settings )
->setConfig( require( CONFIGS_PATH . DIRECTORY_SEPARATOR . 'models_craig_config.php' ) );
return $spp;
}
public function getDalApi() {
return new \DalServices\Api();
}
public function getFeedsService() {
$fc = \Auro\Mvc\Front::getInstance();
$feedsService = new \SomeNamespace\Feeds();
$renderer = new \Auro\View\Renderer();
$renderer->setBasePath( VIEWS_PATH . DIRECTORY_SEPARATOR . 'feeds' );
$feedsService
->setDalApi( new \DalServices\Api() )
->setSomeNamespaceApi( $this )
->setResponse( $fc->getResponse() )
->setPaginator( new \Auro\View\Paginator() )
->setConfig( require( CONFIGS_PATH . DIRECTORY_SEPARATOR . 'models_feeds_config.php' ) )
->setCams( require( CONFIGS_PATH . DIRECTORY_SEPARATOR . 'webcams.php' ) )
->setRenderer( $renderer );
return $feedsService;
}
public function getSettingsService() {
$fc = \Auro\Mvc\Front::getInstance();
$settingsService = new \SomeNamespace\Settings;
$renderer = new \Auro\View\Renderer();
$renderer->setBasePath( VIEWS_PATH . DIRECTORY_SEPARATOR . 'settings' );
$settingsService
->setSomeNamespaceApi( $this )
->setValidator( new \Auro\Validation\Validator() )
->setConfig( require( CONFIGS_PATH . DIRECTORY_SEPARATOR . 'models_craig_config.php' ) )
->setDalApi( new \DalServices\Api() )
->setResponse( $fc->getResponse() )
->setRenderer( $renderer );
return $settingsService;
}
public function getUsersService() {
$fc = \Auro\Mvc\Front::getInstance();
$usersService = new \SomeNamespace\Users();
$renderer = new \Auro\View\Renderer();
$renderer->setBasePath( VIEWS_PATH . DIRECTORY_SEPARATOR . 'users' );
$usersService
->setSomeNamespaceApi( $this )
->setValidator( new \Auro\Validation\Validator() )
->setConfig( require( CONFIGS_PATH . DIRECTORY_SEPARATOR . 'models_craig_config.php' ) )
->setAvailableCurrencies( require( CONFIGS_PATH . DIRECTORY_SEPARATOR . 'currencies.php' ) )
->setLanguages( require( CONFIGS_PATH . DIRECTORY_SEPARATOR . 'languages.php' ) )
->setPostgersqlPreprocessor( $this->getPostgresqlPreprocessor() )
->setResponse( $fc->getResponse() )
->setDalApi( new \DalServices\Api() )
->setRenderer( $renderer );
return $usersService;
}
public function getVrcommentsService() {
$fc = \Auro\Mvc\Front::getInstance();
$vrcommentsService = new \SomeNamespace\Vrcomments();
$renderer = new \Auro\View\Renderer();
$renderer->setBasePath( VIEWS_PATH . DIRECTORY_SEPARATOR . 'vrcomments' );
$vrcommentsService
->setSomeNamespaceApi( $this )
->setValidator( new \Auro\Validation\Validator() )
->setConfig( require( CONFIGS_PATH . DIRECTORY_SEPARATOR . 'models_craig_config.php' ) )
->setPostgersqlPreprocessor( $this->getPostgresqlPreprocessor() )
->setPaginator( new \Auro\View\Paginator() )
->setResponse( $fc->getResponse() )
->setDalApi( new \DalServices\Api() )
->setRenderer( $renderer );
return $vrcommentsService;
}
public function getVrentalsService() {
$fc = \Auro\Mvc\Front::getInstance();
$renderer = new \Auro\View\Renderer();
$renderer->setBasePath( VIEWS_PATH . DIRECTORY_SEPARATOR . 'vrentals' );
$vrentalsService = new \SomeNamespace\Vrentals();
$vrentalsService
->setSomeNamespaceApi( $this )
->setValidator( new \Auro\Validation\Validator() )
->setConfig( require( CONFIGS_PATH . DIRECTORY_SEPARATOR . 'models_craig_config.php' ) )
->setPostgersqlPreprocessor( $this->getPostgresqlPreprocessor() )
->setPaginator( new \Auro\View\Paginator() )
->setDalApi( new \DalServices\Api() )
->setRenderer( $renderer )
->setResponse( $fc->getResponse() )
->setMailConfig( require( CONFIGS_PATH . DIRECTORY_SEPARATOR . 'models_craig_mail.php' ) )
->setMailer( new \PHPMailer( true ) );
return $vrentalsService;
}
public function getNoAikService() {
$fc = \Auro\Mvc\Front::getInstance();
$renderer = new \Auro\View\Renderer();
$renderer->setBasePath( VIEWS_PATH . DIRECTORY_SEPARATOR . 'noaik' );
$AikService = new \SomeNamespace\Noaik();
$noAikService
->setSomeNamespaceApi( $this )
->setValidator( new \Auro\Validation\Validator() )
->setConfig( require( CONFIGS_PATH . DIRECTORY_SEPARATOR . 'models_craig_config.php' ) )
->setPostgersqlPreprocessor( $this->getPostgresqlPreprocessor() )
->setPaginator( new \Auro\View\Paginator() )
->setResponse( $fc->getResponse() )
->setDalApi( new \DalServices\Api() )
->setRenderer( $renderer )
->setMailConfig( require( CONFIGS_PATH . DIRECTORY_SEPARATOR . 'models_craig_mail.php' ) )
->setMailer( new \PHPMailer( true ) );
return $noAikService;
}
public function getTotalauthService() {
$fc = \Auro\Mvc\Front::getInstance();
$renderer = new \Auro\View\Renderer();
$renderer->setBasePath( VIEWS_PATH . DIRECTORY_SEPARATOR . 'totalauth' );
$totalauthService = new \SomeNamespace\Totalauth();
$totalauthService
->setSomeNamespaceApi( $this )
->setValidator( new \Auro\Validation\Validator() )
->setRenderer( $renderer )
->setResponse( $fc->getResponse() )
->setDalApi( new \DalServices\Api() )
->setConfig( require( CONFIGS_PATH . DIRECTORY_SEPARATOR . 'models_totalauth_config.php' ) )
->setMailConfig( require( CONFIGS_PATH . DIRECTORY_SEPARATOR . 'models_totalauth_mail.php' ) )
->setMailer( new \PHPMailer( true ) );
return $totalauthService;
}
public function getQuickmailService() {
$fc = \Auro\Mvc\Front::getInstance();
$quickmailService = new \SomeNamespace\Quickmail();
$quickmailService
->setSomeNamespaceApi( $this )
->setValidator( new \Auro\Validation\Validator() )
->setResponse( $fc->getResponse() )
->setMailConfig( require( CONFIGS_PATH . DIRECTORY_SEPARATOR . 'models_quickmail_mail.php' ) )
->setMailer( new \PHPMailer( true ) );
return $quickmailService;
}
}
?>
Could someone confirm that this is in fact dependency injection container and what can be improved?
Upvotes: 2
Views: 475
Reputation: 15363
This isn't really dependency injection.
Dependency Injection is when a piece of code relies on some other piece of code. The method signatures and expected return values are known, but the implementation is not. You can totally do this in php but its different from what you have done.
This is what dependency injection might look like(Entirely contrived example):
<?php
class PartnerAttachmentReader implements AttachmentReader{
private $titleParsingStrategy;
private function __construct($titleParsingStrategy){
$this->titleParsingStrategy = $titleParsingStrategy;
}
public static function getInstance($titleParsingStrategy){
return new PartnerAttachmentReader($titleParsingStrategy);
}
public function getTitle($attachment){
$this->titleParsingStrategy->parseTitle($attachment)
}
public function parseAttachment(){
//Do Some Parsing
}
}
?>
What is $titleParsingStrategy
? how does it work? unknown. The point is I don't have to care. I can substitute other implementations at my leisure including mock ones at test time.
DI is also useful when dealing with volatile things like disk or network. You can separate the disk and network access in a "dependecy" and test the target of the injection for completeness and correctness without being beholden to network drops or state changes on disk.
Upvotes: 0
Reputation: 71384
To me this looks like a collection of methods to instantiate objects needed by the specific API. I don't know that I would consider it dependency injection in and of itself. It is hard to tell though without seeing how this class is actually used. To me, a dependency injection container would basically containe metadata about how to instantiate various classes that implement a common interface.
So a sample set of classes that might interact to achieve dependency injection might look like:
class db_dependency_provider {
private static $class_map = array(
'postgres' => 'postgres_abstraction_class',
'mysql' => 'mysql_abstraction_class',
'oracle' => 'oracle_abstraction_class'
}
public static function get_db_abstraction($type) {
$class = self::$class_map[$type];
return new $class();
}
}
interface db_abstraction_interface {
public function connect();
public function query($query);
// etc.
}
class mysql_db_abstraction implements db_abstraction_interface {
// actual implementation
}
class postgres_db_abstraction implements db_abstraction_interface {
// actual implementation
}
class some_class_that_needs_a_db {
$db = null;
public function __construct($db) {
$this->db = $db;
}
// other methods
}
// use dependency injection container
$class = new some_class_that_needs_a_db(db_dependency_provider::get_db_abstraction('mysql'));
Upvotes: 1
Reputation: 1670
I posted an answer to a similar question earlier this year. I believe it should address your concern. How can I use "Dependency Injection" in simple php functions, and should I bother?
It looks like you could also benefit from PHP autoloading, which is also available from the Bart project as well as other open source projects like Composer.
For a general dependency injection primer, you might check out Martin Fowler: http://martinfowler.com/articles/injection.html
Upvotes: 1