Skip to content

Commit

Permalink
[TASK] Modernize and improve DI chapter (#5254)
Browse files Browse the repository at this point in the history
* [TASK] Modernize and improve DI chapter

A major rewrite of the DI chapter, looking at
more details, considering more use cases, giving
better best practices and adapting to recent
core changes.

Resolves: #2339
Resolves: #4539
Resolves: #4603
Resolves: #5118

* Update Documentation/ApiOverview/DependencyInjection/Index.rst

* Update Documentation/ApiOverview/DependencyInjection/Index.rst

* [TASK] Admonition refinement, index refinement, re-add Services.php info

---------

Co-authored-by: Garvin Hicking <[email protected]>
Co-authored-by: Garvin Hicking <[email protected]>
  • Loading branch information
3 people authored Jan 22, 2025
1 parent 72c93e1 commit 82ff036
Show file tree
Hide file tree
Showing 24 changed files with 704 additions and 371 deletions.
768 changes: 478 additions & 290 deletions Documentation/ApiOverview/DependencyInjection/Index.rst

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace TYPO3\CMS\Core\Configuration;

use Symfony\Component\DependencyInjection\Attribute\AsAlias;

#[AsAlias('extension-configuration', public: true)]
class ExtensionConfiguration
{
public function get(string $extension, string $path = ''): mixed
{
// implementation
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\Service;

use Symfony\Component\DependencyInjection\Attribute\AsAlias;

#[AsAlias(MyServiceInterface::class)]
class MyDefaultServiceImplementation implements MyServiceInterface
{
public function foo()
{
// do something
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use MyVendor\MyExtension\Service\MyServiceInterface;

class MyController
class MyFirstController
{
public function __construct(
private readonly MyServiceInterface $myService,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\Service;

class MyOtherServiceImplementation implements MyServiceInterface
{
public function foo()
{
// do something
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,11 @@

namespace MyVendor\MyExtension\Controller;

class MySecondController extends MyController {}
use MyVendor\MyExtension\Service\MyServiceInterface;

class MySecondController
{
public function __construct(
private readonly MyServiceInterface $myService,
) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\Service;

use Symfony\Component\DependencyInjection\Attribute\Autowire;

class MyServiceGettingExtensionConfigurationValueInjected
{
public function __construct(
#[Autowire(expression: 'service("extension-configuration").get("my_extension", "something.isEnabled")')]
private readonly bool $somethingIsEnabled,
) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\Service;

use Symfony\Component\DependencyInjection\Attribute\Autowire;

class MyServiceGettingFeatureToggleResultInjected
{
public function __construct(
#[Autowire(expression: 'service("features").isFeatureEnabled("myExtension.foo")')]
private readonly bool $fooEnabled,
) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\Service;

use Symfony\Component\DependencyInjection\Attribute\Autowire;
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;

class MyServiceGettingRuntimeCacheInjected
{
public function __construct(
#[Autowire(service: 'cache.runtime')]
private readonly FrontendInterface $runtimeCache,
) {}

public function calculateSomethingExpensive()
{
// do something using runtime cache
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\Service;

interface MyServiceInterface
{
public function foo();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\Service;

use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;

/**
* This service is instantiated using GeneralUtility::makeInstance()
* in some cases, which requires 'public' being set to 'true'.
*/
#[Autoconfigure(public: true)]
readonly class MyServiceUsingAutoconfigurePublicTrue
{
public function __construct(
private SomeDependency $someDependency,
) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\Service;

use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;

/**
* This service is stateful and configures the service container to
* inject new instances to consuming services when they are instantiated.
*/
#[Autoconfigure(shared: false)]
class MyServiceUsingAutoconfigureSharedFalse
{
private string $foo = 'foo';

public function __construct(
private readonly SomeDependency $someDependency,
) {}

public function setFoo(): void
{
$this->foo = 'bar';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\Service;

use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;

class MyServiceUsingCacheManager
{
private FrontendInterface $runtimeCache;

public function __construct(
CacheManager $cacheManager,
) {
$this->runtimeCache = $cacheManager->getCache('runtime');
}

public function calculateSomethingExpensive()
{
// do something using runtime cache
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use Psr\Clock\ClockInterface;

final class MyClass
final class MyServiceUsingClockInterface
{
public function __construct(
private readonly ClockInterface $clock,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class MyThirdController
{
private MyServiceInterface $myService;

public function injectMyService(MyServiceInterface $myService)
public function injectMyService(MyServiceInterface $myService): void
{
$this->myService = $myService;
}
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
services:
_defaults:
autowire: true
autoconfigure: true
public: false

MyVendor\MyExtension\:
resource: '../Classes/*'

# Declare a "foreign" service "public: true" since this extension needs
# to instantiate the service using GeneralUtility::makeInstance() and
# the service is configured "public: false" by the extension delivering
# that service.
TYPO3\CMS\Core\Some\Service:
public: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
services:

Psr\Clock\ClockInterface:
factory: ['Lcobucci\Clock\SystemClock', 'fromUTC']
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
services:
_defaults:
autowire: true
autoconfigure: true
public: false

# Within MySecondController and MyThirdController different implementations
# than the default MyDefaultServiceImplementation of MyServiceInterface
# shall be injected.

# When working with constructor injection
MyVendor\MyExtension\Controller\MySecondController:
arguments:
$service: '@MyVendor\MyExtension\Service\MyOtherServiceImplementation'

# When working with method injection
MyVendor\MyExtension\Controller\MyThirdController:
calls:
- method: 'injectMyService'
arguments:
$service: '@MyVendor\MyExtension\Service\MyOtherServiceImplementation'

This file was deleted.

0 comments on commit 82ff036

Please sign in to comment.