I just finished rewriting the Zend_Controller to tagged.lebensold.net. I really like how there's no view logic, no HTML and no model-specific code. Note that I'm also injecting the data source (an XML file) into the model. This might seem a bit strange from a model perspective, however it enables me to limit the amount of requests made to disk. What do you think?
class IndexController extends Zend_Controller_Action { const worksXml = '../application/works.xml'; private $defaultId = 2; private $defaultTag = 'still'; private $lastTag; private $xml; private $session; public function init() { $this->session = new Zend_Session_Namespace('Default'); if (!isset($this->session->xmlstr)) $this->session->xmlstr = file_get_contents(self::worksXml); $this->xml = new SimpleXMLElement($this->session->xmlstr); $this->getAllTags(); } /** * The default action - show the home page */ public function indexAction() { if ($this->getRequest()->getParam('tag', false)) { $this->setCurrentTag($this->getRequest()->getParam('tag')); if ($this->lastTag ) { $workIds = WorkModel::GetRelatedWorks($this->session->currentTag, $this->xml); if ($this->session->lastId) { $currentKey = array_search($this->session->lastId , $workIds); if (array_key_exists($currentKey + 1 , $workIds)) $id = $workIds[$currentKey + 1]; else $id = $workIds[0]; } else $id = $workIds[1]; } } else { if (!isset($this->session->currentTag)) $this->view->tagHeader = $this->defaultTag; else $this->view->tagHeader = $this->session->currentTag; } if ($this->getRequest()->getParam('id', false)) { if (! WorkModel::IdExists($this->getRequest()->getParam('id'), $this->xml)) $id = $this->defaultId; else $id = $this->getRequest()->getParam('id'); } if (!isset($id)) $id = WorkModel::GetFirstId($this->view->tagHeader, $this->xml); $this->session->lastId = intval($id); $this->view->work = new WorkModel($id , $this->xml); $this->view->related = WorkModel::GetRelatedWorks($this->view->tagHeader , $this->xml); } private function setCurrentTag($tag) { if ($this->session->currentTag) $this->lastTag = $this->session->currentTag; if (! WorkModel::TagExists($tag , $this->xml) ) { $this->session->currentTag = $this->defaultTag; $this->view->tagHeader = $this->defaultTag; } else { $this->session->currentTag = $tag; $this->view->tagHeader = $tag; } } public function contactAction() { $this->view->work = new WorkModel($this->defaultId ,$this->xml); $this->view->tagHeader = 'contact'; } private function getAllTags() { $this->view->allTags = array(); foreach($this->xml as $work) { for ($i = 0; $i < count($work->tags->tag); $i++) { if (! in_array("" . $work->tags->tag[$i] , $this->view->allTags)) { $this->view->allTags[] = "" . $work->tags->tag[$i]; } } } } }
{ 3 comments… read them below or add one }
Injection
I don’t think that word means what you think it means. XD
My understanding of DI involves inputting an external dependency inside an object, either at the time of its construction, or through a mutator. While in pure OO terms, this isn’t DI because I’m not using an interface or an object, the reason why I would argue it is, is because I’m consuming an XML source which is iterated much like a dataset from a database. My WorkModel has no idea that it’s consuming XML and so I can swap out the XML feed without changing the WorkModel.
Am I way off here?
Dependency injection is about pushing in things from the outside, to give control over internal behaviour to a caller. What you are doing is much more like a configuration file, where the model is pulling in info from outside. The model still has the responsibility to fetch the resource itself.
The reason it’s an important difference is that in this case the model is in control, since it decides what file to include. Dependency injection is about inversion of control, where whoever is managing the Model has control over what dependency is used.