133 lines
4.8 KiB
YAML
133 lines
4.8 KiB
YAML
uuid:
|
|
- value: 22301027-1726-463c-bdfc-a21deca00f34
|
|
langcode:
|
|
- value: en
|
|
type:
|
|
- target_id: daily_email
|
|
target_type: node_type
|
|
target_uuid: 8bde1f2f-eef9-4f2d-ae9c-96921f8193d7
|
|
revision_timestamp:
|
|
- value: '2025-07-14T18:15:51+00:00'
|
|
revision_uid:
|
|
- target_type: user
|
|
target_uuid: b8966985-d4b2-42a7-a319-2e94ccfbb849
|
|
revision_log: { }
|
|
status:
|
|
- value: true
|
|
uid:
|
|
- target_type: user
|
|
target_uuid: b8966985-d4b2-42a7-a319-2e94ccfbb849
|
|
title:
|
|
- value: 'Easier dependency injection with autowiring'
|
|
created:
|
|
- value: '2025-07-11T18:12:23+00:00'
|
|
changed:
|
|
- value: '2025-07-14T18:15:51+00:00'
|
|
promote:
|
|
- value: false
|
|
sticky:
|
|
- value: false
|
|
default_langcode:
|
|
- value: true
|
|
revision_translation_affected:
|
|
- value: true
|
|
path:
|
|
- alias: /daily/2025/07/11/easier-dependency-injection-autowiring
|
|
langcode: en
|
|
body:
|
|
- value: |-
|
|
Dependency injection is, as the name suggests, the approach of injecting dependencies into a class - usually within a `__construct` method.
|
|
|
|
This makes code less coupled and easier to test.
|
|
|
|
In a Drupal application, that usually means not using the static methods on `\Drupal` when fetching dependencies.
|
|
|
|
This is an example from my website:
|
|
|
|
```php
|
|
<?php
|
|
|
|
readonly final class PodcastNodeRepository {
|
|
|
|
private NodeStorageInterface $nodeStorage;
|
|
|
|
public function __construct(EntityTypeManagerInterface $entityTypeManager) {
|
|
$this->nodeStorage = $entityTypeManager->getStorage('node');
|
|
}
|
|
|
|
}
|
|
```
|
|
|
|
The `EntityTypeManagerInterface` dependency is injected and used to get the node storage class, which is used in another method to find the podcast episode nodes.
|
|
|
|
For this to work with the dependency injection container, I need to add the class as a service, including its arguments so they can be injected:
|
|
|
|
```yaml
|
|
# opd_podcast.services.yml
|
|
|
|
services:
|
|
Drupal\opd_podcast\Action\GetNextPodcastEpisodeNumber:
|
|
arguments:
|
|
- '@entity_type.manager'
|
|
```
|
|
|
|
But, this means you need to update this file if any dependencies change.
|
|
|
|
Wouldn't it be better to do this automatically?
|
|
|
|
Usually, it can with autowiring.
|
|
|
|
Instead of `arguments`, add `autowire: true` and Drupal will try to automatically inject the dependencies for you:
|
|
|
|
```yaml
|
|
# opd_podcast.services.yml
|
|
|
|
services:
|
|
Drupal\opd_podcast\Action\GetNextPodcastEpisodeNumber:
|
|
autowire: true
|
|
Drupal\opd_podcast\Repository\PodcastNodeRepository:
|
|
autowire: true
|
|
```
|
|
|
|
Now, if dependencies change, you don't need to update the services file - making it easier and quicker.
|
|
format: markdown
|
|
processed: |
|
|
<p>Dependency injection is, as the name suggests, the approach of injecting dependencies into a class - usually within a <code>__construct</code> method.</p>
|
|
<p>This makes code less coupled and easier to test.</p>
|
|
<p>In a Drupal application, that usually means not using the static methods on <code>\Drupal</code> when fetching dependencies.</p>
|
|
<p>This is an example from my website:</p>
|
|
<pre><code><?php
|
|
|
|
readonly final class PodcastNodeRepository {
|
|
|
|
private NodeStorageInterface $nodeStorage;
|
|
|
|
public function __construct(EntityTypeManagerInterface $entityTypeManager) {
|
|
$this->nodeStorage = $entityTypeManager->getStorage('node');
|
|
}
|
|
|
|
}
|
|
</code></pre><p>The <code>EntityTypeManagerInterface</code> dependency is injected and used to get the node storage class, which is used in another method to find the podcast episode nodes.</p>
|
|
<p>For this to work with the dependency injection container, I need to add the class as a service, including its arguments so they can be injected:</p>
|
|
<pre><code># opd_podcast.services.yml
|
|
|
|
services:
|
|
Drupal\opd_podcast\Action\GetNextPodcastEpisodeNumber:
|
|
arguments:
|
|
- '@entity_type.manager'
|
|
</code></pre><p>But, this means you need to update this file if any dependencies change.</p>
|
|
<p>Wouldn't it be better to do this automatically?</p>
|
|
<p>Usually, it can with autowiring.</p>
|
|
<p>Instead of <code>arguments</code>, add <code>autowire: true</code> and Drupal will try to automatically inject the dependencies for you:</p>
|
|
<pre><code># opd_podcast.services.yml
|
|
|
|
services:
|
|
Drupal\opd_podcast\Action\GetNextPodcastEpisodeNumber:
|
|
autowire: true
|
|
Drupal\opd_podcast\Repository\PodcastNodeRepository:
|
|
autowire: true
|
|
</code></pre><p>Now, if dependencies change, you don't need to update the services file - making it easier and quicker.</p>
|
|
summary: ''
|
|
field_daily_email_cta:
|
|
- target_type: node
|
|
target_uuid: e3f6c728-7855-4804-8614-e2a0c08c368f
|