Dependency injection
Hubleto creates its services with a small dependency injection container, Hubleto\Framework\DependencyInjection. You do not call it directly. You use getService(), or a shortcut such as $this->router() or $this->db().
Getting a service
/** @var \Hubleto\App\Community\Invoices\Services\PriceCalculator $calculator */
$calculator = $this->getService(\Hubleto\App\Community\Invoices\Services\PriceCalculator::class);
- The first call creates the object with
new. Every other call returns the same instance (a singleton for the request). - The class must have a constructor without required parameters.
getService()is available in every class that extendsHubleto\Erp\Core: models, controllers, apps, crons, listeners and services.
getModel() and getController() are only typed shortcuts of getService(), so a model and a controller are singletons as well. Do not keep data of one record or one request in a property of a model.
To get a fresh object, call DependencyInjection::create($class, true).
Your own service
Put the class into Services/ of your app (see Services) and call getService():
apps/PriceLists/Services/Counter.php (excerpt)
namespace Hubleto\App\Community\PriceLists\Services;
use Hubleto\App\Community\PriceLists\Models\History;
use Hubleto\App\Community\PriceLists\Models\PriceList;
/**
* Counters used in the sidebar badge, alerts, dashboards and crons.
*/
class Counter extends \Hubleto\Erp\Core
Replacing a service
A service provider tells the container "when somebody asks for class A, create class B". The ERP replaces the framework services with its own classes:
src/Loader.php (excerpt)
DependencyInjection::setServiceProviders([
\Hubleto\Framework\Services\Renderer::class => Renderer::class,
\Hubleto\Framework\Services\Env::class => Env::class,
\Hubleto\Framework\Services\Locale::class => Locale::class,
\Hubleto\Framework\Controllers\NotFound::class => Controllers\NotFound::class,
\Hubleto\Framework\Controllers\Desktop::class => \Hubleto\App\Community\Desktop\Controllers\Desktop::class,
]);
DependencyInjection::setServiceProvider($original, $replacement) registers one mapping and setServiceProviders([...]) a list. The replacement should extend the original class, so everything that uses the original keeps working.
use Hubleto\Framework\DependencyInjection;
DependencyInjection::setServiceProvider(
\Hubleto\App\Community\Documents\Generator::class,
\HubletoProject\Services\MyGenerator::class
);
NOTE A mapping has an effect only for services that have not been created yet. Register it as early as possible: after the autoloader is loaded, before the services are used. The
src/dependencies/folder of the project skeleton is reserved for such classes.
