diff --git a/core/core.api.php b/core/core.api.php index 93ad0576f29df03827c42fd92dbb497a01eb9e59..fb612f23dbf5ef9cf18ed1f24dc7244d904c6bee 100644 --- a/core/core.api.php +++ b/core/core.api.php @@ -852,6 +852,12 @@ * Services can also be defined dynamically, as in the * \Drupal\Core\CoreServiceProvider class, but this is less common for modules. * + * @section sec_define Service autowiring + * Instead of specifying arguments explicitly, the container can also autowire + * a service's arguments from the constructor's type-hints. See + * @link https://symfony.com/doc/current/service_container/autowiring.html the Symfony documentation on defining services dependencies automatically @endlink + * for details. + * * @section sec_tags Service tags * Some services have tags, which are defined in the service definition. See * @link service_tag Service Tags @endlink for usage. diff --git a/core/misc/cspell/dictionary.txt b/core/misc/cspell/dictionary.txt index 80d6cb2fc6795b4bea1a56410f88a70899180164..f6328a4e3f1cf06645403afa4ed8fa88eaecac10 100644 --- a/core/misc/cspell/dictionary.txt +++ b/core/misc/cspell/dictionary.txt @@ -110,6 +110,7 @@ autosave autosubmit autowire autowired +autowiring backend's backlink backlinks diff --git a/core/modules/system/tests/modules/autowire_test/autowire_test.info.yml b/core/modules/system/tests/modules/autowire_test/autowire_test.info.yml new file mode 100644 index 0000000000000000000000000000000000000000..e121afef6cc00b2f7cfe19896dcea25b87c2bc03 --- /dev/null +++ b/core/modules/system/tests/modules/autowire_test/autowire_test.info.yml @@ -0,0 +1,5 @@ +name: 'Auto-wiring test' +type: module +description: 'Support module for auto-wiring testing.' +package: Testing +version: VERSION diff --git a/core/modules/system/tests/modules/autowire_test/autowire_test.services.yml b/core/modules/system/tests/modules/autowire_test/autowire_test.services.yml new file mode 100644 index 0000000000000000000000000000000000000000..8111f39a56dc7b9f2ff13a6b55feae70694479cc --- /dev/null +++ b/core/modules/system/tests/modules/autowire_test/autowire_test.services.yml @@ -0,0 +1,22 @@ +services: + # Multiple services that implements TestInjectionInterface. + # These are marked private, because they are only intended to be used as + # dependencies injected into other services. + Drupal\autowire_test\TestInjection: + public: false + Drupal\autowire_test\TestInjection2: + public: false + + # An alias that specifies which service to use by default for arguments that + # type-hint to the interface. + # This is marked private, because it is only intended to be used as a + # dependency injected into other services. + Drupal\autowire_test\TestInjectionInterface: + alias: 'Drupal\autowire_test\TestInjection' + public: false + + # A service that tests autowiring for two constructor arguments: + # - One type-hinted to TestInjectionInterface. + # - One type-hinted to TestInjection2. + Drupal\autowire_test\TestService: + autowire: true diff --git a/core/modules/system/tests/modules/autowire_test/src/TestInjection.php b/core/modules/system/tests/modules/autowire_test/src/TestInjection.php new file mode 100644 index 0000000000000000000000000000000000000000..c49d856fd9d44e415000656c93877cf90069430f --- /dev/null +++ b/core/modules/system/tests/modules/autowire_test/src/TestInjection.php @@ -0,0 +1,9 @@ +<?php + +namespace Drupal\autowire_test; + +/** + * A service that is autowired. + */ +class TestInjection implements TestInjectionInterface { +} diff --git a/core/modules/system/tests/modules/autowire_test/src/TestInjection2.php b/core/modules/system/tests/modules/autowire_test/src/TestInjection2.php new file mode 100644 index 0000000000000000000000000000000000000000..83e1e38221280c5bc394fae18866c0e1a174cc19 --- /dev/null +++ b/core/modules/system/tests/modules/autowire_test/src/TestInjection2.php @@ -0,0 +1,9 @@ +<?php + +namespace Drupal\autowire_test; + +/** + * A service that is autowired. + */ +class TestInjection2 { +} diff --git a/core/modules/system/tests/modules/autowire_test/src/TestInjectionInterface.php b/core/modules/system/tests/modules/autowire_test/src/TestInjectionInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..b9bb38252c0ec2cbf6d0d7a2b5a6e67c7132712b --- /dev/null +++ b/core/modules/system/tests/modules/autowire_test/src/TestInjectionInterface.php @@ -0,0 +1,9 @@ +<?php + +namespace Drupal\autowire_test; + +/** + * An interface for a service that is autowired. + */ +interface TestInjectionInterface { +} diff --git a/core/modules/system/tests/modules/autowire_test/src/TestService.php b/core/modules/system/tests/modules/autowire_test/src/TestService.php new file mode 100644 index 0000000000000000000000000000000000000000..23febc6ae304b613307c771eb0cfb3f90a31861f --- /dev/null +++ b/core/modules/system/tests/modules/autowire_test/src/TestService.php @@ -0,0 +1,30 @@ +<?php + +namespace Drupal\autowire_test; + +class TestService { + + /** + * @var \Drupal\autowire_test\TestInjectionInterface + */ + protected $testInjection; + + /** + * @var \Drupal\autowire_test\TestInjection2 + */ + protected $testInjection2; + + public function __construct(TestInjectionInterface $test_injection, TestInjection2 $test_injection2) { + $this->testInjection = $test_injection; + $this->testInjection2 = $test_injection2; + } + + public function getTestInjection(): TestInjectionInterface { + return $this->testInjection; + } + + public function getTestInjection2(): TestInjection2 { + return $this->testInjection2; + } + +} diff --git a/core/tests/Drupal/KernelTests/Core/DependencyInjection/AutowireTest.php b/core/tests/Drupal/KernelTests/Core/DependencyInjection/AutowireTest.php new file mode 100644 index 0000000000000000000000000000000000000000..08052c74e5d5c6569d2f86d5fd77a2902cafe605 --- /dev/null +++ b/core/tests/Drupal/KernelTests/Core/DependencyInjection/AutowireTest.php @@ -0,0 +1,32 @@ +<?php + +namespace Drupal\KernelTests\Core\DependencyInjection; + +use Drupal\autowire_test\TestInjection; +use Drupal\autowire_test\TestInjection2; +use Drupal\autowire_test\TestService; +use Drupal\KernelTests\KernelTestBase; + +/** + * Tests auto-wiring services. + * + * @group DependencyInjection + */ +class AutowireTest extends KernelTestBase { + + /** + * {@inheritdoc} + */ + protected static $modules = ['autowire_test']; + + /** + * Tests that 'autowire_test.service' has its dependencies injected. + */ + public function testAutowire(): void { + // Ensure an autowired interface works. + $this->assertInstanceOf(TestInjection::class, $this->container->get(TestService::class)->getTestInjection()); + // Ensure an autowired class works. + $this->assertInstanceOf(TestInjection2::class, $this->container->get(TestService::class)->getTestInjection2()); + } + +}