Anax DI
, (*1)
, (*2)
, (*3)
, (*4)
Anax DI service container for dependency injection of framework services using creation and lazy loading of services., (*5)
The implementation of the container is compliant with PHP-FIG
PSR-11: Container interface, (*6)
Table of content
You can also read this documentation online., (*7)
Install
You can install the module from anax/di
on Packagist using composer., (*8)
composer require anax/di
Development
To work as a developer you clone the repo and install the local environment through make. Then you can run the unit tests., (*9)
make install
make test
Basic usage
This is the basic usage of the container., (*10)
First you create the container., (*11)
// Create it
$di = new \Anax\DI\DI();
// Check its a PSR-11 interface
assert($di instanceof \Psr\Container\ContainerInterface);
Add services onto the container., (*12)
// Add a service
$di->set("response", "\Anax\Response\Response");
// Add a shared service
$di->setShared("view", "\Anax\View\ViewContainer");
Check if the service is loaded., (*13)
// Check if service is loaded
if ($di->has("view")) {
; // the service is loaded
}
Get and use the service., (*14)
// Get and use a service
$response = $di->get("response");
$response->addBody($body)->send();
// Same, without storing in a variable
$di->get("response")->addBody($body)->send();
Shared service
A shared service always return the same object. The object is instantiated once and then stored for the next wanting to use the service. There is only one instance af a shared service. The service is shared among all its users., (*15)
// Add a shared service
$di->setShared("view", "\Anax\View\ViewContainer");
// Get two instances of the shared service
$view1 = $di->get("view");
$view2 = $di->get("view");
assert($view1 === $view2);
A service that is not shared will return a new instance each time it is get from the container., (*16)
// Add a service
$di->set("response", "\Anax\Response\Response");
// Get two instances of the service
$response1 = $di->get("response");
$response2 = $di->get("response");
assert($response1 !== $response2);
Lazy loading
The services added to the container are not activated until accessed. They are lazy loaded to ensure they are only active when used., (*17)
You can see what services are loaded onto the container and you can see what services are activated., (*18)
// Add services
$di->set("response", "\Anax\Response\Response");
$di->setShared("view", "\Anax\View\ViewContainer");
// Get one service
$response = $di->get("response");
// Check what services are loaded
implode(",", $di->getServices()); // response,view
// Check what services are active
implode(",", $di->getActiveServices()); // response
Usage in Anax
In Anax all services are loaded during the bootstrap phase in the file htdocs/index.php
. It looks like this., (*19)
// Add all framework services to $di
$di = new Anax\DI\DIFactoryConfig();
$di->loadServices(ANAX_INSTALL_PATH . "/config/di");
The variable $di
is the only global variable within the framework. The main dependency, as a global variable, is to the be accessable within the view template files and view helpers., (*20)
Anax initialization of services
All the framework services are loaded from files in the directory ANAX_INSTALL_PATH . "/config/di"
. Each file contains one service. A file can contain several services., (*21)
This is a example of a service configuration file for the service "request"., (*22)
/**
* Configuration file for request service.
*/
return [
// Services to add to the container.
"services" => [
"request" => [
"shared" => true,
"callback" => function () {
$obj = new \Anax\Request\Request();
$obj->init();
return $obj;
}
],
],
];
A service may contain a callback that initiates the service when it is loaded. The callback should return the initiated object., (*23)
The service can be defined through its class name when the service needs no extra initialisation., (*24)
"callback" => "\Anax\Request\Request",
One common way to initialize the service is to inject $di
into the service. This is an example of that., (*25)
"response" => [
"shared" => true,
//"callback" => "\Anax\Response\Response",
"callback" => function () {
$obj = new \Anax\Response\ResponseUtility();
$obj->setDI($this);
return $obj;
}
],
Anax configuration of services
During the initialization phase some services might want to read additional configuration information. They can do so by using anax/configuration
, like this., (*26)
First, lets have a look at the service "configuration"., (*27)
"configuration" => [
"shared" => true,
"callback" => function () {
$config = new \Anax\Configure\Configuration();
$dirs = require ANAX_INSTALL_PATH . "/config/configuration.php";
$config->setBaseDirectories($dirs);
return $config;
}
],
It is a service to read configuration files from those directories that the framework specifies. It can be used like this, when creating other services that depends on their own configuration files., (*28)
"session" => [
"active" => defined("ANAX_WITH_SESSION") && ANAX_WITH_SESSION, // true|false
"shared" => true,
"callback" => function () {
$session = new \Anax\Session\Session();
// Load the configuration files
$cfg = $this->get("configuration");
$config = $cfg->load("session");
// Set various settings in the $session
// ...
return $session;
}
],
The configuration setting "active" states wether the service should be activated when its loaded, or if it should be lazy loaded., (*29)
In the callback, first the service "configuration" is retrieved from $di. Then it is used to read the configuration file named "session"., (*30)
The actual configuration is returned from the configuration file "session" and can then be used to configure and setup the object, before returning it as a framework service., (*31)
A configuration file is in general stored by its service name in ANAX_INSTALL_PATH . "/config/servicename.php"
. It should return something, like this., (*32)
/**
* Config-file for sessions.
*/
return [
// Session name
"name" => preg_replace("/[^a-z\d]/i", "", __DIR__),
];
Dependency
Using psr11 through psr/container
., (*33)
License
This software carries a MIT license. See LICENSE.txt for details., (*34)
.
..: Copyright (c) 2013 - 2018 Mikael Roos, mos@dbwebb.se