Documentation/Container/Receiving service

Accessing a Service from the Container

Direct access to the container's content is implemented in several ways. To choose the appropriate method suitable for coding a specific project, it is necessary to consider the pros and cons of each approach, as well as their testing options.


#Reference to the Container in the Current Class

Classes inherited from the Hleb\Base\Container class gain additional capabilities in the form of methods and the $this->container property to access services. The standard framework classes — controllers, middlewares, commands, events — are already inherited from this class.

If a service in the container interface has its own method assigned, the service can be accessed through this method. Example of accessing a demo service in a controller:

<?php
// File /app/Controllers/ExampleController.php

namespace App\Controllers;

use 
App\Bootstrap\Services\RequestIdInterface;
use 
Hleb\Base\Controller;

class 
ExampleController extends Controller
{
    public function 
index(): void
    
{
        
// variant 1
        
$requestIdService $this->container->get(RequestIdInterface::class);
        
// variant 2
        
$requestIdService $this->container->requestId();
    }
}

The reference to the container is stored in the $this->config property (key 'container' in the array) of the object class inherited from Hleb\Base\Container. When creating the specified object, a different value can be assigned (for example, with a test container) in the 'config' argument.
Otherwise, if a specific container is not specified in the 'config' argument or the 'config' argument of the constructor is missing, the container will be created by default.

<?php

use App\Bootstrap\Services\RequestIdInterface;

class 
ExampleService extends \Hleb\Base\Container
{
    public 
RequestIdInterface $service;

    public function 
__construct(array $config = [])
    {
        
parent::__construct($config);

        
$this->service $this->container->get(RequestIdInterface::class);
    }
}

// Create an object with a framework container.
$requestIdService = (new ExampleService())->service;

// Create an object with a test container.
$config = ['container' => new TestContainer()];
$requestIdService = (new ExampleService($config))->service;

Exceptions are the Model classes, where accessing the service similarly will be as follows:

<?php
// File /app/Models/DefaultModel.php

namespace App\Models;

use 
App\Bootstrap\Services\RequestIdInterface;
use 
Hleb\Base\Model;

class 
DefaultModel extends Model
{
    public static function 
getCollection(): array
    {
        
// variant 1
        
$requestIdService self::container()->get(RequestIdInterface::class);
        
// variant 2
        
$requestIdService self::container()->requestId();

        return [];
    }
}

#Container Class

Access to the service container is also provided by the Hleb\Static\Container class, for example:

use App\Bootstrap\Services\RequestIdInterface;
use 
Hleb\Static\Container;

// variant 1
$container Container::getContainer();
$requestIdService $container->get(RequestIdInterface::class);

// variant 2
$requestIdService Container::get(RequestIdInterface::class);

#Standard Services

In the /vendor/phphleb/framework/Static/ folder, there are wrapper classes over the framework's standard services, which can be used in code similarly to the Hleb\Static\Container class, but for individual services.
These services can also be accessed using the previously mentioned methods.

Due to the existence of different approaches in naming interfaces, accessing standard services from the container can be either with or without the Interface suffix. For example, Hleb\Reference\RequestInterface is equivalent to Hleb\Reference\Interface\Request.

Container Structure Dependency Injection

Page translated: chatgpt 4-o
Back to top