Skip to content

Commit 2ebf996

Browse files
josbeirmarkstory
andauthored
Update dependency injection docs for the built-in container (#8363)
* Update dependency injection docs for the built-in container Refs cakephp/cakephp#19559, cakephp/cakephp#19696, cakephp/cakephp#19716. * Update docs/en/appendices/6-0-migration-guide.md --------- Co-authored-by: Mark Story <mark@mark-story.com>
1 parent 62b1e16 commit 2ebf996

3 files changed

Lines changed: 63 additions & 79 deletions

File tree

‎docs/en/appendices/6-0-migration-guide.md‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,21 @@ Some properties have also been renamed to better reflect their purpose. These ar
110110
argument will need to be updated to pass it as the 3rd argument instead or
111111
use named parameters.
112112

113+
### Dependency Injection
114+
115+
- CakePHP now uses `Cake\Container\Container` by default and no longer requires
116+
`league/container`. Remove the old `App.container = 'cake'` config option. To use a
117+
custom container, set `App.container` to a class name implementing
118+
`Cake\Container\ContainerInterface`.
119+
- Replace `Cake\Core\Container`, `Cake\Core\ContainerInterface` and
120+
`Cake\Core\ServiceProvider` with their `Cake\Container` equivalents.
121+
- Auto-wiring and its resolution cache are enabled by default. Remove delegation
122+
to `League\Container\ReflectionContainer`; use `disableAutoWiring()` and
123+
`enableAutoWiring()` to configure the built-in resolver. See
124+
[Auto-wiring](../development/dependency-injection#auto-wiring) for details.
125+
- `Container::defaultToShared()`, `enableAutoWiring()` and `disableAutoWiring()`
126+
return `static`. Update the return types of overrides accordingly.
127+
113128
### Datasource
114129

115130
- `Datasource/Paging/PaginatedInterface` now extends `IteratorAggregate`

‎docs/en/development/dependency-injection.md‎

Lines changed: 46 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -597,9 +597,9 @@ public function services(ContainerInterface $container): void
597597
> [!NOTE]
598598
> CakePHP's dependency injection container uses [PSR-11](https://www.php-fig.org/psr/psr-11/) for compatibility with other frameworks and libraries.
599599
600-
In order to have services created by the container, you need to tell it which
601-
classes it can create and how to build those classes. The
602-
simplest definition is via a class name:
600+
The container can auto-wire concrete classes. Define services explicitly to
601+
configure their construction, map interfaces to implementations, or control
602+
sharing. The simplest definition is via a class name:
603603

604604
```php
605605
// Add a class by its name.
@@ -614,7 +614,7 @@ Your application and plugins define the services they have in the
614614
namespace App;
615615

616616
use App\Service\BillingService;
617-
use Cake\Core\ContainerInterface;
617+
use Cake\Container\ContainerInterface;
618618
use Cake\Http\BaseApplication;
619619

620620
class Application extends BaseApplication
@@ -649,8 +649,9 @@ $container->add(AuditLogServiceInterface::class, function (...$args) {
649649
Factory functions will receive all the resolved dependencies for the class
650650
as arguments.
651651

652-
Once you've defined a class, you also need to define the dependencies it
653-
requires. Those dependencies can be either objects or primitive values:
652+
Class-typed constructor dependencies can be auto-wired. Define arguments
653+
explicitly for primitive values or dependencies that cannot be resolved from
654+
their type:
654655

655656
```php
656657
// Add a primitive value like a string, array or number.
@@ -772,8 +773,8 @@ An example ServiceProvider would look like:
772773
```php
773774
namespace App\ServiceProvider;
774775

775-
use Cake\Core\ContainerInterface;
776-
use Cake\Core\ServiceProvider;
776+
use Cake\Container\ContainerInterface;
777+
use Cake\Container\ServiceProvider;
777778
// Other imports here.
778779

779780
class BillingServiceProvider extends ServiceProvider
@@ -817,7 +818,8 @@ example of a bootable service would be:
817818
```php
818819
namespace App\ServiceProvider;
819820

820-
use Cake\Core\ServiceProvider;
821+
use Cake\Container\ContainerInterface;
822+
use Cake\Container\ServiceProvider;
821823
// Other imports here.
822824

823825
class BillingServiceProvider extends ServiceProvider
@@ -1327,70 +1329,15 @@ class ArticlesController extends AppController
13271329
> - **Clarity**: Controller focuses on HTTP concerns, service handles business logic
13281330
> - **Maintainability**: Complex workflows are organized into focused classes
13291331
1330-
## Auto-wiring with league/container
1332+
<a id="auto-wiring-with-leaguecontainer"></a>
1333+
<a id="built-in-container"></a>
13311334

1332-
> [!WARNING]
1333-
> Auto-wiring is convenient but can impact performance. Enable caching in production environments.
1335+
## Auto-wiring
13341336

1335-
When using the default `league/container` implementation, auto-wiring is turned
1336-
off by default. To enable it:
1337-
1338-
```php
1339-
// In src/Application.php
1340-
use League\Container\ReflectionContainer;
1341-
1342-
public function services(ContainerInterface $container): void
1343-
{
1344-
$container->delegate(
1345-
new ReflectionContainer(),
1346-
);
1347-
}
1348-
```
1349-
1350-
While your dependencies will now be resolved automatically, this approach will
1351-
not cache resolutions which can be detrimental to performance. To enable
1352-
caching:
1353-
1354-
```php
1355-
use League\Container\ReflectionContainer;
1356-
1357-
$container->delegate(
1358-
// or consider using the value of Configure::read('debug')
1359-
new ReflectionContainer(true),
1360-
);
1361-
```
1362-
1363-
Read more about auto wiring in the [PHP League Container documentation](https://container.thephpleague.com/4.x/auto-wiring/).
1364-
1365-
## Built-in Container
1366-
1367-
::: info Added in version 5.4.0
1368-
:::
1369-
1370-
CakePHP includes its own PSR-11-compatible dependency injection container in
1371-
the `Cake\Container` namespace. The `league/container` implementation remains
1372-
the default so that existing applications continue to work unchanged. To use
1373-
the built-in container, set `App.container` to `cake` in `config/app.php`:
1374-
1375-
```php
1376-
return [
1377-
'App' => [
1378-
'container' => 'cake',
1379-
],
1380-
];
1381-
```
1382-
1383-
CakePHP exposes the built-in container through a compatibility bridge. Continue
1384-
to type-hint `Cake\Core\ContainerInterface` in your application's `services()`
1385-
method; service definitions using `add()`, `addShared()`, `extend()`, tags, and
1386-
delegates work with either implementation.
1387-
1388-
### Auto-wiring
1389-
1390-
Unlike the default `league/container` implementation, the built-in container
1391-
enables auto-wiring and caches auto-wired resolutions by default. It can create
1392-
concrete classes and resolve their class-typed constructor dependencies without
1393-
an explicit service definition:
1337+
CakePHP uses its built-in PSR-11 container, `Cake\Container\Container`, by
1338+
default. Auto-wiring and caching of auto-wired resolutions are enabled. The
1339+
container can create concrete classes and resolve their class-typed constructor
1340+
dependencies without an explicit definition:
13941341

13951342
```php
13961343
class OrderService
@@ -1402,14 +1349,36 @@ class OrderService
14021349

14031350
// Only the interface needs an explicit mapping. OrderService is auto-wired.
14041351
$container->add(PaymentGateway::class, StripePaymentGateway::class);
1352+
$service = $container->get(OrderService::class);
14051353
```
14061354

14071355
Define services explicitly when a constructor needs an interface, a scalar or
14081356
array value, or another value that cannot be determined from its type. Explicit
1409-
definitions also let you configure constructor arguments and control whether a
1410-
service is shared.
1357+
definitions also let you configure arguments and control whether a service is
1358+
shared. Auto-wiring caches resolved instances; this differs from explicit
1359+
definitions, which are not shared unless registered with `addShared()`.
1360+
1361+
Use `hasDefinition()` to check for an explicit registration. `has()` also checks
1362+
delegates, including the auto-wiring resolver, so it can return true for an
1363+
unregistered concrete class.
1364+
1365+
To disable auto-wiring, call `disableAutoWiring()` before adding any custom
1366+
delegates, as that method clears all delegates. To enable auto-wiring without
1367+
caching resolved instances:
1368+
1369+
```php
1370+
$container->disableAutoWiring()->enableAutoWiring(false);
1371+
```
1372+
1373+
### Controller Actions and Commands
1374+
1375+
Class-typed controller action arguments are resolved from explicit definitions
1376+
first, then matching passed arguments, then default parameter values. If none
1377+
applies, an instantiable concrete class can be auto-wired. Optional arguments
1378+
with a default of `null` keep that default unless a definition or passed value
1379+
is available.
14111380

1412-
When using the built-in container, do not add
1413-
`League\Container\ReflectionContainer`; auto-wiring is already enabled. The
1414-
following [auto-wiring instructions](#auto-wiring-with-leaguecontainer) apply
1415-
only when using the default `league/container` implementation.
1381+
Command constructor dependencies can also be auto-wired. Interfaces and scalar
1382+
arguments still need explicit definitions. Controller construction itself uses
1383+
explicit definitions; it does not automatically resolve arbitrary controllers
1384+
through auto-wiring.

‎docs/en/plugins.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ like:
312312
namespace ContactManager;
313313

314314
use Cake\Core\BasePlugin;
315-
use Cake\Core\ContainerInterface;
315+
use Cake\Container\ContainerInterface;
316316
use Cake\Core\PluginApplicationInterface;
317317
use Cake\Console\CommandCollection;
318318
use Cake\Event\EventManagerInterface;
@@ -366,7 +366,7 @@ class ContactManagerPlugin extends BasePlugin
366366
/**
367367
* Register application container services.
368368
*
369-
* @param \Cake\Core\ContainerInterface $container The Container to update.
369+
* @param \Cake\Container\ContainerInterface $container The Container to update.
370370
* @return void
371371
* @link https://book.cakephp.org/5/en/development/dependency-injection.html#dependency-injection
372372
*/

0 commit comments

Comments
 (0)