Skip to content

Instantly share code, notes, and snippets.

@dongilbert
Last active December 17, 2015 03:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dongilbert/5542570 to your computer and use it in GitHub Desktop.
Save dongilbert/5542570 to your computer and use it in GitHub Desktop.
Joomla\DI\Container

Joomla\DI\Container

A Dependency Injection container for Joomla. It allows you to pass a key and callback via array syntax to a Joomla\DI\Container instance to help manage the lifesycle of an object.

The callback receives the current instance of the container as it's only (optional) argument. You can reference it to anything, I prefer to use $c (for 'container'). All the public methods of the container are avialable within the callback.

$config = array(
	'mailer.username' => 'foo',
	'mailer.password' => 'bar'
);

$dic = new \Joomla\DI\Container($config);

$dic['mailerTransport'] = function($c)
{
	return new Zend_Mail_Transport_Smtp('smtp.gmail.com', array(
		'auth'     => 'login',
		'username' => $c->getParam('mailer.username'),
		'password' => $c->getParam('mailer.password'),
		'ssl'      => 'ssl',
		'port'     => 465
	));
};

Creating an Application Instance

A very simplistic example that is obviously overkill for this situation. The AbstractWebApplication takes a Joomla\Input\Input dependency in the constructor.

class App extends \Joomla\Application\AbstractWebApplication { /* required methods */ }

$dic = new Joomla\DI\Container;

$dic['input'] = function ()
{
	// Use $_GET data only
	return new \Joomla\Input\Input($_GET);
}

$dic['app'] = function ($c)
{
	return new App($c['input']);
};

$dic['app']->execute();

To Do

  • Add more (extended) examples
  • Better documentation
<?php
/**
* Potentially Part of the Joomla Framework DI Package
*
* @copyright Copyright (C) 2013 Don Gilbert. All rights reserved.
* @license LGPL version 2 or later; see http://www.gnu.org/licenses/old-licenses/lgpl-2.0.html
*/
namespace Joomla\DI;
class Container implements \ArrayAccess
{
/**
* Holds the shared instances.
*
* @var array $instances
*
* @since 1.0
*/
private $instances = array();
/**
* Holds the keys, their callbacks, and whether or not
* the item is meant to be a shared resource.
*
* @var array $dataStore
*
* @since 1.0
*/
private $dataStore = array();
/**
* Holds config options accessible within the passed callback.
*
* @var array $config
*
* @since 1.0
*/
public $config = array('default.shared' => true);
/**
* Constructor for the DI Container
*
* @param array $config Array of configuration parameters.
*
* @since 1.0
*/
public function __construct(array $config = array())
{
$this->setConfig($config);
}
/**
* Method to set the key and callback to the dataStore array.
*
* @param string $key Name of dataStore key to set.
* @param callable $callback Callable function to run when requesting the specified $key.
* @param boolean $shared True to create and store a shared instance.
*
* @return Joomla\DI\Container This instance to support chaining.
*
* @since 1.0
*/
public function set($key, $callback, $shared = true)
{
if (isset($this->dataStore[$key]))
{
throw new \OutOfBoundsException(sprintf('Key %s has already been assigned.', $key));
}
if (!is_callable($callback))
{
throw new \UnexpectedValueException('Provided value is not a valid callback.');
}
$this->dataStore[$key] = array(
'callback' => $callback,
'shared' => $shared
);
return $this;
}
/**
* Method to retrieve the results of running the $callback for the specified $key;
*
* @param string $key Name of the dataStore key to get.
*
* @return mixed Results of running the $callback for the specified $key.
*
* @since 1.0
*/
public function get($key)
{
if (!isset($this->dataStore[$key]))
{
throw new \InvalidArgumentException(sprintf('Key %s has not been registered with the container.', $key));
}
if ($this->dataStore[$key]['shared'])
{
if (!isset($this->instances[$key]))
{
$this->instances[$key] = $this->dataStore[$key]['callback']($this);
}
return $this->instances[$key];
}
return $this->dataStore[$key]['callback']($this);
}
/**
* Method to set an array of config options.
*
* @param array $config Associative array to merge with the internal config.
*
* @return Joomla\DI\Container This instance to support chaining.
*
* @since 1.0
*/
public function setConfig(array $config)
{
$this->config = array_merge($this->config, $config);
return $this;
}
/**
* Method to retrieve the entire config array.
*
* @return array The config array for this instance.
*
* @since 1.0
*/
public function getConfig()
{
return $this->config;
}
/**
* Method to set a single config option.
*
* @param string $key Name of config key.
* @param mixed $value Value of config key.
*
* @return Joomla\DI\Container This instance to support chaining.
*
* @since 1.0
*/
public function setParam($key, $value)
{
$this->config[$key] = $value;
return $this;
}
/**
* Method to retrieve a single configuration parameter.
*
* @param string $key Name of config key to retrieve.
*
* @return mixed Value of config $key or null if not yet set.
*
* @since 1.0
*/
public function getParam($key)
{
return isset($this->config[$key]) ? $this->config[$key] : null;
}
/**
* Whether an offset exists.
*
* @param string $key Name of the bindings key to check if exists.
*
* @return boolean True if the specified offset exists.
*
* @since 1.0
*/
public function offsetExists($key)
{
return isset($this->dataStore[$key]);
}
/**
* Offset to retrieve.
*
* @param string $key Name of the dataStore key to get.
*
* @return mixed Results of running the $callback for the specified $key.
*
* @since 1.0
*/
public function offsetGet($key)
{
return $this->get($key);
}
/**
* Offset to set.
*
* @param string $key Name of dataStore key to set.
* @param callable $callback Callable function to run when requesting $key.
*
* @return void
*
* @since 1.0
*/
public function offsetSet($key, $callback)
{
$this->set($key, $callback, $this->config['default.shared']);
}
/**
* Offset to unset.
*
* @param string $key Offset to unset.
*
* @return void
*
* @since 1.0
*/
public function offsetUnset($key)
{
unset($this->dataStore[$key]);
}
}
@eddieajau
Copy link

I like the simplicity a lot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment