diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php
index 81d7233811f1b..c82f98675f3e1 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/JsonDescriptor.php
@@ -222,6 +222,7 @@ private function getContainerDefinitionData(Definition $definition, $omitTags =
'shared' => $definition->isShared(),
'abstract' => $definition->isAbstract(),
'autowire' => $definition->isAutowired(),
+ 'autoconfigure' => $definition->isAutoconfigured(),
);
foreach ($definition->getAutowiringTypes(false) as $autowiringType) {
diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php
index c0319aad6bb19..2b10d3610b116 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/MarkdownDescriptor.php
@@ -183,6 +183,7 @@ protected function describeContainerDefinition(Definition $definition, array $op
."\n".'- Shared: '.($definition->isShared() ? 'yes' : 'no')
."\n".'- Abstract: '.($definition->isAbstract() ? 'yes' : 'no')
."\n".'- Autowired: '.($definition->isAutowired() ? 'yes' : 'no')
+ ."\n".'- Autoconfigured: '.($definition->isAutoconfigured() ? 'yes' : 'no')
;
foreach ($definition->getAutowiringTypes(false) as $autowiringType) {
diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php
index 40e749aa6a3e7..f9e90e30ec1bb 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php
@@ -372,6 +372,7 @@ private function getContainerDefinitionDocument(Definition $definition, $id = nu
$serviceXML->setAttribute('shared', $definition->isShared() ? 'true' : 'false');
$serviceXML->setAttribute('abstract', $definition->isAbstract() ? 'true' : 'false');
$serviceXML->setAttribute('autowired', $definition->isAutowired() ? 'true' : 'false');
+ $serviceXML->setAttribute('autoconfigured', $definition->isAutoconfigured() ? 'true' : 'false');
$serviceXML->setAttribute('file', $definition->getFile());
$calls = $definition->getMethodCalls();
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
index 9a757e8082aa6..666b4cc31088d 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -13,30 +13,49 @@
use Doctrine\Common\Annotations\Reader;
use Symfony\Bridge\Monolog\Processor\DebugProcessor;
+use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Cache\Adapter\AdapterInterface;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\Config\Resource\DirectoryResource;
+use Symfony\Component\Config\ResourceCheckerInterface;
use Symfony\Component\Console\Application;
+use Symfony\Component\Console\Command\Command;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\LogicException;
-use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
+use Symfony\Component\DependencyInjection\Reference;
+use Symfony\Component\DependencyInjection\ServiceSubscriberInterface;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
use Symfony\Component\Finder\Finder;
+use Symfony\Component\Form\FormTypeGuesserInterface;
+use Symfony\Component\Form\FormTypeInterface;
+use Symfony\Component\HttpKernel\CacheClearer\CacheClearerInterface;
+use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
+use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\PropertyAccess\PropertyAccessor;
-use Symfony\Component\Serializer\Encoder\YamlEncoder;
+use Symfony\Component\PropertyInfo\PropertyAccessExtractorInterface;
+use Symfony\Component\PropertyInfo\PropertyDescriptionExtractorInterface;
+use Symfony\Component\PropertyInfo\PropertyListExtractorInterface;
+use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
use Symfony\Component\Serializer\Encoder\CsvEncoder;
+use Symfony\Component\Serializer\Encoder\EncoderInterface;
+use Symfony\Component\Serializer\Encoder\YamlEncoder;
use Symfony\Component\Serializer\Mapping\Factory\CacheClassMetadataFactory;
use Symfony\Component\Serializer\Normalizer\DataUriNormalizer;
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
use Symfony\Component\Serializer\Normalizer\JsonSerializableNormalizer;
+use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
+use Symfony\Component\Validator\ConstraintValidatorInterface;
+use Symfony\Component\Validator\ObjectInitializerInterface;
use Symfony\Component\WebLink\HttpHeaderSerializer;
use Symfony\Component\Workflow;
@@ -225,6 +244,45 @@ public function load(array $configs, ContainerBuilder $container)
'Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller',
));
+ $container->registerForAutoconfiguration(Command::class)
+ ->addTag('console.command');
+ $container->registerForAutoconfiguration(ResourceCheckerInterface::class)
+ ->addTag('config_cache.resource_checker');
+ $container->registerForAutoconfiguration(ServiceSubscriberInterface::class)
+ ->addTag('container.service_subscriber');
+ $container->registerForAutoconfiguration(AbstractController::class)
+ ->addTag('controller.service_arguments');
+ $container->registerForAutoconfiguration(Controller::class)
+ ->addTag('controller.service_arguments');
+ $container->registerForAutoconfiguration(DataCollectorInterface::class)
+ ->addTag('data_collector');
+ $container->registerForAutoconfiguration(FormTypeInterface::class)
+ ->addTag('form.type');
+ $container->registerForAutoconfiguration(FormTypeGuesserInterface::class)
+ ->addTag('form.type_guesser');
+ $container->registerForAutoconfiguration(CacheClearerInterface::class)
+ ->addTag('kernel.cache_clearer');
+ $container->registerForAutoconfiguration(CacheWarmerInterface::class)
+ ->addTag('kernel.cache_warmer');
+ $container->registerForAutoconfiguration(EventSubscriberInterface::class)
+ ->addTag('kernel.event_subscriber');
+ $container->registerForAutoconfiguration(PropertyListExtractorInterface::class)
+ ->addTag('property_info.list_extractor');
+ $container->registerForAutoconfiguration(PropertyTypeExtractorInterface::class)
+ ->addTag('property_info.type_extractor');
+ $container->registerForAutoconfiguration(PropertyDescriptionExtractorInterface::class)
+ ->addTag('property_info.description_extractor');
+ $container->registerForAutoconfiguration(PropertyAccessExtractorInterface::class)
+ ->addTag('property_info.access_extractor');
+ $container->registerForAutoconfiguration(EncoderInterface::class)
+ ->addTag('serializer.encoder');
+ $container->registerForAutoconfiguration(NormalizerInterface::class)
+ ->addTag('serializer.normalizer');
+ $container->registerForAutoconfiguration(ConstraintValidatorInterface::class)
+ ->addTag('validator.constraint_validator');
+ $container->registerForAutoconfiguration(ObjectInitializerInterface::class)
+ ->addTag('validator.initializer');
+
if (PHP_VERSION_ID < 70000) {
$this->addClassesToCompile(array(
'Symfony\\Component\\Config\\ConfigCache',
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/alias_with_definition_1.json b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/alias_with_definition_1.json
index 09260d6159036..efcf34d06aa77 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/alias_with_definition_1.json
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/alias_with_definition_1.json
@@ -11,6 +11,7 @@
"shared": true,
"abstract": true,
"autowire": false,
+ "autoconfigure": false,
"file": null,
"factory_class": "Full\\Qualified\\FactoryClass",
"factory_method": "get",
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/alias_with_definition_1.md b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/alias_with_definition_1.md
index cb539aa795b16..ac56c0d4a4aff 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/alias_with_definition_1.md
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/alias_with_definition_1.md
@@ -12,5 +12,6 @@
- Shared: yes
- Abstract: yes
- Autowired: no
+- Autoconfigured: no
- Factory Class: `Full\Qualified\FactoryClass`
- Factory Method: `get`
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/alias_with_definition_1.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/alias_with_definition_1.xml
index 5515332b0875b..19f5a04344fef 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/alias_with_definition_1.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/alias_with_definition_1.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/alias_with_definition_2.json b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/alias_with_definition_2.json
index 03b4f36e13616..03780e3eebe7a 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/alias_with_definition_2.json
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/alias_with_definition_2.json
@@ -11,6 +11,7 @@
"shared": true,
"abstract": false,
"autowire": false,
+ "autoconfigure": false,
"file": "\/path\/to\/file",
"factory_service": "factory.service",
"factory_method": "get",
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/alias_with_definition_2.md b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/alias_with_definition_2.md
index 6ebc5b8512f70..406c5dcada7a4 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/alias_with_definition_2.md
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/alias_with_definition_2.md
@@ -12,6 +12,7 @@
- Shared: yes
- Abstract: no
- Autowired: no
+- Autoconfigured: no
- File: `/path/to/file`
- Factory Service: `factory.service`
- Factory Method: `get`
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/alias_with_definition_2.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/alias_with_definition_2.xml
index c549e50e59763..3c15460beebe8 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/alias_with_definition_2.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/alias_with_definition_2.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.json b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.json
index 7c43445239fb9..c304b33ac2283 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.json
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.json
@@ -8,6 +8,7 @@
"shared": true,
"abstract": true,
"autowire": false,
+ "autoconfigure": false,
"arguments": [
{
"type": "service",
@@ -22,6 +23,7 @@
"shared": true,
"abstract": false,
"autowire": false,
+ "autoconfigure": false,
"arguments": [
"arg1",
"arg2"
@@ -43,6 +45,7 @@
"shared": true,
"abstract": false,
"autowire": false,
+ "autoconfigure": false,
"arguments": [],
"file": null,
"tags": []
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.md b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.md
index 1f1635e581494..29e34d2b0d94f 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.md
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.md
@@ -13,6 +13,7 @@ Definitions
- Shared: yes
- Abstract: yes
- Autowired: no
+- Autoconfigured: no
- Arguments: yes
- Factory Class: `Full\Qualified\FactoryClass`
- Factory Method: `get`
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.xml
index f74ad13d7be74..2d4de06aa84cb 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_arguments.xml
@@ -2,12 +2,12 @@
-
+
%parameter%
-
+
arg1
arg2
@@ -16,7 +16,7 @@
foo
-
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_public.json b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_public.json
index 43cf434d26f6b..7f86ccb2ac429 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_public.json
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_public.json
@@ -8,6 +8,7 @@
"shared": true,
"abstract": true,
"autowire": false,
+ "autoconfigure": false,
"file": null,
"factory_class": "Full\\Qualified\\FactoryClass",
"factory_method": "get",
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_public.md b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_public.md
index d21d18053677f..aff2f08191d00 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_public.md
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_public.md
@@ -13,6 +13,7 @@ Definitions
- Shared: yes
- Abstract: yes
- Autowired: no
+- Autoconfigured: no
- Factory Class: `Full\Qualified\FactoryClass`
- Factory Method: `get`
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_public.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_public.xml
index 52031e59aa4ac..22a7fb4224127 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_public.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_public.xml
@@ -2,7 +2,7 @@
-
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_services.json b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_services.json
index 794a10a1c74b1..becd607b797a5 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_services.json
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_services.json
@@ -8,6 +8,7 @@
"shared": true,
"abstract": true,
"autowire": false,
+ "autoconfigure": false,
"file": null,
"factory_class": "Full\\Qualified\\FactoryClass",
"factory_method": "get",
@@ -21,6 +22,7 @@
"shared": true,
"abstract": false,
"autowire": false,
+ "autoconfigure": false,
"file": "\/path\/to\/file",
"factory_service": "factory.service",
"factory_method": "get",
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_services.md b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_services.md
index 26ea2f007ed51..54655668b435b 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_services.md
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_services.md
@@ -13,6 +13,7 @@ Definitions
- Shared: yes
- Abstract: yes
- Autowired: no
+- Autoconfigured: no
- Factory Class: `Full\Qualified\FactoryClass`
- Factory Method: `get`
@@ -25,6 +26,7 @@ Definitions
- Shared: yes
- Abstract: no
- Autowired: no
+- Autoconfigured: no
- File: `/path/to/file`
- Factory Service: `factory.service`
- Factory Method: `get`
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_services.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_services.xml
index bde934fa50a39..54da4f4f48427 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_services.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_services.xml
@@ -2,10 +2,10 @@
-
+
-
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tag1.json b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tag1.json
index 63f26d0a89237..fb9634f67a309 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tag1.json
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tag1.json
@@ -8,6 +8,7 @@
"shared": true,
"abstract": false,
"autowire": false,
+ "autoconfigure": false,
"file": "\/path\/to\/file",
"factory_service": "factory.service",
"factory_method": "get",
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tag1.md b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tag1.md
index e3dcc59f43bff..9895f1fb5d8b2 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tag1.md
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tag1.md
@@ -13,6 +13,7 @@ Definitions
- Shared: yes
- Abstract: no
- Autowired: no
+- Autoconfigured: no
- File: `/path/to/file`
- Factory Service: `factory.service`
- Factory Method: `get`
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tag1.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tag1.xml
index d679db7b3b860..9c39b653dd5fc 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tag1.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tag1.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tags.json b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tags.json
index 42477a04228b6..7f49ac241ffde 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tags.json
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tags.json
@@ -8,6 +8,7 @@
"shared": true,
"abstract": false,
"autowire": false,
+ "autoconfigure": false,
"file": "\/path\/to\/file",
"factory_service": "factory.service",
"factory_method": "get",
@@ -25,6 +26,7 @@
"shared": true,
"abstract": false,
"autowire": false,
+ "autoconfigure": false,
"file": "\/path\/to\/file",
"factory_service": "factory.service",
"factory_method": "get",
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tags.md b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tags.md
index a0e1bcd1c4f8a..205596259d2c6 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tags.md
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tags.md
@@ -13,6 +13,7 @@ tag1
- Shared: yes
- Abstract: no
- Autowired: no
+- Autoconfigured: no
- File: `/path/to/file`
- Factory Service: `factory.service`
- Factory Method: `get`
@@ -31,6 +32,7 @@ tag2
- Shared: yes
- Abstract: no
- Autowired: no
+- Autoconfigured: no
- File: `/path/to/file`
- Factory Service: `factory.service`
- Factory Method: `get`
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tags.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tags.xml
index 08352fa206877..4e98e77a19a23 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tags.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/builder_1_tags.xml
@@ -1,7 +1,7 @@
-
+
@@ -9,7 +9,7 @@
-
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_1.json b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_1.json
index 2a24db63498fe..940bab12699b1 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_1.json
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_1.json
@@ -6,6 +6,7 @@
"shared": true,
"abstract": true,
"autowire": false,
+ "autoconfigure": false,
"file": null,
"factory_class": "Full\\Qualified\\FactoryClass",
"factory_method": "get",
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_1.md b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_1.md
index b1d46b69f4f9f..e4d0429b9087d 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_1.md
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_1.md
@@ -5,5 +5,6 @@
- Shared: yes
- Abstract: yes
- Autowired: no
+- Autoconfigured: no
- Factory Class: `Full\Qualified\FactoryClass`
- Factory Method: `get`
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_1.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_1.xml
index 67d102945a6fe..d5015fdde3bd7 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_1.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_1.xml
@@ -1,4 +1,4 @@
-
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_2.json b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_2.json
index fe83d858dc002..1c7b1ae14af42 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_2.json
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_2.json
@@ -6,6 +6,7 @@
"shared": true,
"abstract": false,
"autowire": false,
+ "autoconfigure": false,
"file": "\/path\/to\/file",
"factory_service": "factory.service",
"factory_method": "get",
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_2.md b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_2.md
index 1f097a2585321..6ff6d60b3dc93 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_2.md
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_2.md
@@ -5,6 +5,7 @@
- Shared: yes
- Abstract: no
- Autowired: no
+- Autoconfigured: no
- File: `/path/to/file`
- Factory Service: `factory.service`
- Factory Method: `get`
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_2.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_2.xml
index 434a34b2565c4..72319eca97a4c 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_2.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_2.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.json b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.json
index ad4ada52a9cd4..0590d3f76a611 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.json
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.json
@@ -6,6 +6,7 @@
"shared": true,
"abstract": true,
"autowire": false,
+ "autoconfigure": false,
"arguments": [
{
"type": "service",
@@ -20,6 +21,7 @@
"shared": true,
"abstract": false,
"autowire": false,
+ "autoconfigure": false,
"arguments": [
"arg1",
"arg2"
@@ -41,6 +43,7 @@
"shared": true,
"abstract": false,
"autowire": false,
+ "autoconfigure": false,
"arguments": [],
"file": null,
"tags": []
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.md b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.md
index b4637aa023c0e..7cee17ad9cbb4 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.md
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.md
@@ -5,6 +5,7 @@
- Shared: yes
- Abstract: yes
- Autowired: no
+- Autoconfigured: no
- Arguments: yes
- Factory Class: `Full\Qualified\FactoryClass`
- Factory Method: `get`
\ No newline at end of file
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.xml
index 85935808c6b90..6d3cb8eea40be 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_1.xml
@@ -1,10 +1,10 @@
-
+
%parameter%
-
+
arg1
arg2
@@ -13,7 +13,7 @@
foo
-
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_2.json b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_2.json
index 7385e98f11ea5..8f65d27b83ea9 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_2.json
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_2.json
@@ -6,6 +6,7 @@
"shared": true,
"abstract": false,
"autowire": false,
+ "autoconfigure": false,
"arguments": [],
"file": "\/path\/to\/file",
"factory_service": "factory.service",
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_2.md b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_2.md
index 7ffe0e551af55..abe7dd475db2c 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_2.md
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_2.md
@@ -5,6 +5,7 @@
- Shared: yes
- Abstract: no
- Autowired: no
+- Autoconfigured: no
- Arguments: no
- File: `/path/to/file`
- Factory Service: `factory.service`
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_2.xml b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_2.xml
index 434a34b2565c4..72319eca97a4c 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_2.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Fixtures/Descriptor/definition_arguments_2.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php
index 520ccd6daf5f1..3099a7d359240 100644
--- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php
+++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php
@@ -19,13 +19,13 @@
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
-use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Security\Core\Authorization\ExpressionLanguage;
+use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
/**
* SecurityExtension.
@@ -110,6 +110,9 @@ public function load(array $configs, ContainerBuilder $container)
$this->aclLoad($config['acl'], $container);
}
+ $container->registerForAutoconfiguration(VoterInterface::class)
+ ->addTag('security.voter');
+
if (PHP_VERSION_ID < 70000) {
// add some required classes for compilation
$this->addClassesToCompile(array(
diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php
index 790ab41a79df7..8e37cbba871b8 100644
--- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php
+++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php
@@ -13,6 +13,7 @@
use Symfony\Bridge\Twig\Extension\WebLinkExtension;
use Symfony\Component\Config\FileLocator;
+use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
@@ -143,6 +144,11 @@ public function load(array $configs, ContainerBuilder $container)
$container->getDefinition('twig')->replaceArgument(1, $config);
+ $container->registerForAutoconfiguration(\Twig_ExtensionInterface::class)
+ ->addTag('twig.extension');
+ $container->registerForAutoconfiguration(\Twig_LoaderInterface::class)
+ ->addTag('twig.loader');
+
if (PHP_VERSION_ID < 70000) {
$this->addClassesToCompile(array(
'Twig_Environment',
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php
index 4e0b007c2a362..0be05dea23bcb 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php
@@ -101,6 +101,7 @@ private function doResolveDefinition(ChildDefinition $definition)
$def->setPublic($parentDef->isPublic());
$def->setLazy($parentDef->isLazy());
$def->setAutowired($parentDef->isAutowired());
+ $def->setAutoconfigured($parentDef->isAutoconfigured());
$def->setChanges($parentDef->getChanges());
// overwrite with values specified in the decorator
@@ -129,6 +130,9 @@ private function doResolveDefinition(ChildDefinition $definition)
if (isset($changes['autowired'])) {
$def->setAutowired($definition->isAutowired());
}
+ if (isset($changes['autoconfigured'])) {
+ $def->setAutoconfigured($definition->isAutoconfigured());
+ }
if (isset($changes['shared'])) {
$def->setShared($definition->isShared());
}
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php
index 479fe12559639..b8800fe901454 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php
@@ -38,25 +38,37 @@ public function process(ContainerBuilder $container)
private function processDefinition(ContainerBuilder $container, $id, Definition $definition)
{
- if (!$instanceofConditionals = $definition->getInstanceofConditionals()) {
+ $instanceofConditionals = $definition->getInstanceofConditionals();
+ $automaticInstanceofConditionals = $definition->isAutoconfigured() ? $container->getAutomaticInstanceofDefinitions() : array();
+
+ if (!$instanceofConditionals && !$automaticInstanceofConditionals) {
return $definition;
}
+
if (!$class = $container->getParameterBag()->resolveValue($definition->getClass())) {
return $definition;
}
+ $conditionals = $this->mergeConditionals($automaticInstanceofConditionals, $instanceofConditionals);
+
$definition->setInstanceofConditionals(array());
$parent = $shared = null;
$instanceofTags = array();
- foreach ($instanceofConditionals as $interface => $instanceofDef) {
+ foreach ($conditionals as $interface => $instanceofDefs) {
if ($interface !== $class && (!$container->getReflectionClass($interface) || !$container->getReflectionClass($class))) {
continue;
}
- if ($interface === $class || is_subclass_of($class, $interface)) {
+
+ if ($interface !== $class && !is_subclass_of($class, $interface)) {
+ continue;
+ }
+
+ foreach ($instanceofDefs as $key => $instanceofDef) {
+ /** @var ChildDefinition $instanceofDef */
$instanceofDef = clone $instanceofDef;
$instanceofDef->setAbstract(true)->setInheritTags(false)->setParent($parent ?: 'abstract.instanceof.'.$id);
- $parent = 'instanceof.'.$interface.'.'.$id;
+ $parent = 'instanceof.'.$interface.'.'.$key.'.'.$id;
$container->setDefinition($parent, $instanceofDef);
$instanceofTags[] = $instanceofDef->getTags();
$instanceofDef->setTags(array());
@@ -100,4 +112,20 @@ private function processDefinition(ContainerBuilder $container, $id, Definition
return $definition;
}
+
+ private function mergeConditionals(array $automaticInstanceofConditionals, array $instanceofConditionals)
+ {
+ // make each value an array of ChildDefinition
+ $conditionals = array_map(function($childDef) { return array($childDef); }, $automaticInstanceofConditionals);
+
+ foreach ($instanceofConditionals as $interface => $instanceofDef) {
+ if (!isset($automaticInstanceofConditionals[$interface])) {
+ $conditionals[$interface] = array();
+ }
+
+ $conditionals[$interface][] = $instanceofDef;
+ }
+
+ return $conditionals;
+ }
}
diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php
index 86099458f807a..bab790ee2ab70 100644
--- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php
+++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php
@@ -118,6 +118,8 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
*/
private $vendors;
+ private $automaticInstanceofDefinitions = array();
+
public function __construct(ParameterBagInterface $parameterBag = null)
{
parent::__construct($parameterBag);
@@ -638,6 +640,14 @@ public function merge(ContainerBuilder $container)
$this->envCounters[$env] += $count;
}
}
+
+ foreach ($container->getAutomaticInstanceofDefinitions() as $interface => $childDefinition) {
+ if (isset($this->automaticInstanceofDefinitions[$interface])) {
+ throw new InvalidArgumentException(sprintf('%s has already been autoconfigured and merge() does not support merging autoconfiguration for the same class/interface.', $interface));
+ }
+
+ $this->automaticInstanceofDefinitions[$interface] = $childDefinition;
+ }
}
/**
@@ -1259,6 +1269,31 @@ public function getExpressionLanguageProviders()
return $this->expressionLanguageProviders;
}
+ /**
+ * Returns a ChildDefinition that will be used for autoconfiguring the interface/class.
+ *
+ * @param string $interface The class or interface to match
+ * @return ChildDefinition
+ */
+ public function registerForAutoconfiguration($interface)
+ {
+ if (!isset($this->automaticInstanceofDefinitions[$interface])) {
+ $this->automaticInstanceofDefinitions[$interface] = new ChildDefinition('');
+ }
+
+ return $this->automaticInstanceofDefinitions[$interface];
+ }
+
+ /**
+ * Returns an array of ChildDefinition[] keyed by interface.
+ *
+ * @return ChildDefinition[]
+ */
+ public function getAutomaticInstanceofDefinitions()
+ {
+ return $this->automaticInstanceofDefinitions;
+ }
+
/**
* Resolves env parameter placeholders in a string or an array.
*
diff --git a/src/Symfony/Component/DependencyInjection/Definition.php b/src/Symfony/Component/DependencyInjection/Definition.php
index af7bb5ee8072f..8599b968b769a 100644
--- a/src/Symfony/Component/DependencyInjection/Definition.php
+++ b/src/Symfony/Component/DependencyInjection/Definition.php
@@ -30,6 +30,7 @@ class Definition
private $properties = array();
private $calls = array();
private $instanceof = array();
+ private $autoconfigured = false;
private $configurator;
private $tags = array();
private $public = true;
@@ -388,6 +389,30 @@ public function getInstanceofConditionals()
return $this->instanceof;
}
+ /**
+ * Sets whether or not instanceof conditionals should be prepended with a global set.
+ *
+ * @param bool $autoconfigured
+ *
+ * @return $this
+ */
+ public function setAutoconfigured($autoconfigured)
+ {
+ $this->changes['autoconfigured'] = true;
+
+ $this->autoconfigured = $autoconfigured;
+
+ return $this;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isAutoconfigured()
+ {
+ return $this->autoconfigured;
+ }
+
/**
* Sets tags for this definition.
*
diff --git a/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php
index 302b3b081f280..c00c2167e2bab 100644
--- a/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php
+++ b/src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php
@@ -205,6 +205,10 @@ private function addService($definition, $id, \DOMElement $parent)
$service->appendChild($autowiringType);
}
+ if ($definition->isAutoconfigured()) {
+ $service->setAttribute('autoconfigure', 'true');
+ }
+
if ($callable = $definition->getConfigurator()) {
$configurator = $this->document->createElement('configurator');
diff --git a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
index 8ea27b4e1677d..c31fc7fd502bd 100644
--- a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
+++ b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
@@ -180,6 +180,9 @@ private function getServiceDefaults(\DOMDocument $xml, $file)
if ($defaultsNode->hasAttribute('inherit-tags')) {
$defaults['inherit-tags'] = XmlUtils::phpize($defaultsNode->getAttribute('inherit-tags'));
}
+ if ($defaultsNode->hasAttribute('autoconfigure')) {
+ $defaults['autoconfigure'] = XmlUtils::phpize($defaultsNode->getAttribute('autoconfigure'));
+ }
return $defaults;
}
@@ -229,6 +232,9 @@ private function parseDefinition(\DOMElement $service, $file, array $defaults =
if (isset($defaults['autowire'])) {
$definition->setAutowired($defaults['autowire']);
}
+ if (isset($defaults['autoconfigure'])) {
+ $definition->setAutoconfigured($defaults['autoconfigure']);
+ }
$definition->setChanges(array());
}
@@ -248,6 +254,10 @@ private function parseDefinition(\DOMElement $service, $file, array $defaults =
$definition->setAutowired(XmlUtils::phpize($value));
}
+ if ($value = $service->getAttribute('autoconfigure')) {
+ $definition->setAutoconfigured(XmlUtils::phpize($value));
+ }
+
if ($files = $this->getChildren($service, 'file')) {
$definition->setFile($files[0]->nodeValue);
}
diff --git a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
index 52e91883eb3c8..735cb8244d0cc 100644
--- a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
+++ b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
@@ -57,6 +57,7 @@ class YamlFileLoader extends FileLoader
'decoration_priority' => 'decoration_priority',
'autowire' => 'autowire',
'autowiring_types' => 'autowiring_types',
+ 'autoconfigure' => 'autoconfigure',
);
private static $prototypeKeywords = array(
@@ -75,6 +76,7 @@ class YamlFileLoader extends FileLoader
'tags' => 'tags',
'inherit_tags' => 'inherit_tags',
'autowire' => 'autowire',
+ 'autoconfigure' => 'autoconfigure',
);
private static $instanceofKeywords = array(
@@ -86,6 +88,7 @@ class YamlFileLoader extends FileLoader
'calls' => 'calls',
'tags' => 'tags',
'autowire' => 'autowire',
+ 'autoconfigure' => 'autoconfigure',
);
private static $defaultsKeywords = array(
@@ -93,6 +96,7 @@ class YamlFileLoader extends FileLoader
'tags' => 'tags',
'inherit_tags' => 'inherit_tags',
'autowire' => 'autowire',
+ 'autoconfigure' => 'autoconfigure',
);
private $yamlParser;
@@ -369,6 +373,9 @@ private function parseDefinition($id, $service, $file, array $defaults)
if (isset($defaults['autowire'])) {
$definition->setAutowired($defaults['autowire']);
}
+ if (isset($defaults['autoconfigure'])) {
+ $definition->setAutoconfigured($defaults['autoconfigure']);
+ }
$definition->setChanges(array());
}
@@ -510,6 +517,10 @@ private function parseDefinition($id, $service, $file, array $defaults)
}
}
+ if (isset($service['autoconfigure'])) {
+ $definition->setAutoconfigured($service['autoconfigure']);
+ }
+
if (array_key_exists('resource', $service)) {
if (!is_string($service['resource'])) {
throw new InvalidArgumentException(sprintf('A "resource" attribute must be of type string for service "%s" in %s. Check your YAML syntax.', $id, $file));
diff --git a/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd b/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd
index 79a9ad4637cf6..c659694ffaa39 100644
--- a/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd
+++ b/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd
@@ -104,6 +104,7 @@
+
@@ -132,6 +133,7 @@
+
@@ -146,6 +148,7 @@
+
@@ -167,6 +170,7 @@
+
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.php
index 962020700bdf0..9d75c0b962186 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.php
@@ -130,6 +130,7 @@ public function testInstanceofDefaultsAndParentDefinitionResolution()
// instanceof overrides defaults
$simpleService = $container->getDefinition('service_simple');
$this->assertFalse($simpleService->isAutowired());
+ $this->assertFalse($simpleService->isAutoconfigured());
$this->assertFalse($simpleService->isShared());
// all tags are kept
@@ -156,6 +157,7 @@ public function testInstanceofDefaultsAndParentDefinitionResolution()
// service override instanceof
$overrideService = $container->getDefinition('service_override_instanceof');
$this->assertTrue($overrideService->isAutowired());
+ $this->assertTrue($overrideService->isAutoconfigured());
// children definitions get no instanceof
$childDef = $container->getDefinition('child_service');
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php
index 4a21f4a53b28c..a2dd9b130d536 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php
@@ -381,6 +381,38 @@ public function testProcessSetsArguments()
$this->assertSame(array(2, 1, 'foo' => 3), $def->getArguments());
}
+ public function testSetAutoconfiguredOnServiceHasParent()
+ {
+ $container = new ContainerBuilder();
+
+ $container->register('parent', 'stdClass')
+ ->setAutoconfigured(true)
+ ;
+
+ $container->setDefinition('child1', new ChildDefinition('parent'))
+ ->setAutoconfigured(false)
+ ;
+
+ $this->process($container);
+
+ $this->assertFalse($container->getDefinition('child1')->isAutoconfigured());
+ }
+
+ public function testSetAutoconfiguredOnServiceIsParent()
+ {
+ $container = new ContainerBuilder();
+
+ $container->register('parent', 'stdClass')
+ ->setAutoconfigured(true)
+ ;
+
+ $container->setDefinition('child1', new ChildDefinition('parent'));
+
+ $this->process($container);
+
+ $this->assertTrue($container->getDefinition('child1')->isAutoconfigured());
+ }
+
protected function process(ContainerBuilder $container)
{
$pass = new ResolveDefinitionTemplatesPass();
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php
index 0829aa8b3efd1..06ae31f08504c 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php
@@ -15,6 +15,7 @@
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\Compiler\ResolveInstanceofConditionalsPass;
use Symfony\Component\DependencyInjection\Compiler\ResolveDefinitionTemplatesPass;
+use Symfony\Component\DependencyInjection\Compiler\ResolveTagsInheritancePass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class ResolveInstanceofConditionalsPassTest extends TestCase
@@ -29,7 +30,7 @@ public function testProcess()
(new ResolveInstanceofConditionalsPass())->process($container);
- $parent = 'instanceof.'.parent::class.'.foo';
+ $parent = 'instanceof.'.parent::class.'.0.foo';
$def = $container->getDefinition('foo');
$this->assertEmpty($def->getInstanceofConditionals());
$this->assertInstanceof(ChildDefinition::class, $def);
@@ -106,4 +107,51 @@ public function testProcessHandlesMultipleInheritance()
$this->assertTrue($def->isLazy());
$this->assertTrue($def->isShared());
}
+
+ public function testProcessUsesAutomaticInstanceofDefinitions()
+ {
+ $container = new ContainerBuilder();
+ $def = $container->register('normal_service', self::class);
+ $def->setInstanceofConditionals(array(
+ parent::class => (new ChildDefinition(''))
+ ->addTag('local_instanceof_tag')
+ ->setFactory('locally_set_factory'),
+ ));
+ $def->setAutoconfigured(true);
+ $container->registerForAutoconfiguration(parent::class)
+ ->addTag('automatic_instanceof_tag')
+ ->setAutowired(true)
+ ->setFactory('automatically_set_factory');
+
+ (new ResolveInstanceofConditionalsPass())->process($container);
+ (new ResolveTagsInheritancePass())->process($container);
+ (new ResolveDefinitionTemplatesPass())->process($container);
+
+ $def = $container->getDefinition('normal_service');
+ // autowired thanks to the automatic instanceof
+ $this->assertTrue($def->isAutowired());
+ // factory from the specific instanceof overrides global one
+ $this->assertEquals('locally_set_factory', $def->getFactory());
+ // tags are merged, the locally set one is first
+ $this->assertSame(array('local_instanceof_tag' => array(array()), 'automatic_instanceof_tag' => array(array())), $def->getTags());
+ }
+
+ public function testProcessDoesNotUseAutomaticInstanceofDefinitionsIfNotEnabled()
+ {
+ $container = new ContainerBuilder();
+ $def = $container->register('normal_service', self::class);
+ $def->setInstanceofConditionals(array(
+ parent::class => (new ChildDefinition(''))
+ ->addTag('foo_tag'),
+ ));
+ $container->registerForAutoconfiguration(parent::class)
+ ->setAutowired(true);
+
+ (new ResolveInstanceofConditionalsPass())->process($container);
+ (new ResolveDefinitionTemplatesPass())->process($container);
+
+ $def = $container->getDefinition('normal_service');
+ // no automatic_tag, it was not enabled on the Definition
+ $this->assertFalse($def->isAutowired());
+ }
}
diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php
index 5580d3c3a4f1a..94d99db9dcff1 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php
@@ -567,6 +567,26 @@ public function testMerge()
$this->assertSame(array('%env(Bar)%'), $config->resolveEnvPlaceholders(array($bag->get('env(Bar)'))));
$container->merge($config);
$this->assertEquals(array('Foo' => 0, 'Bar' => 1), $container->getEnvCounters());
+
+ $container = new ContainerBuilder();
+ $config = new ContainerBuilder();
+ $childDefA = $container->registerForAutoconfiguration('AInterface');
+ $childDefB = $config->registerForAutoconfiguration('BInterface');
+ $container->merge($config);
+ $this->assertSame(array('AInterface' => $childDefA, 'BInterface' => $childDefB), $container->getAutomaticInstanceofDefinitions());
+ }
+
+ /**
+ * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
+ * @expectedExceptionMessage AInterface has already been autoconfigured and merge() does not support merging autoconfiguration for the same class/interface.
+ */
+ public function testMergeThrowsExceptionForDuplicateAutomaticInstanceofDefinitions()
+ {
+ $container = new ContainerBuilder();
+ $config = new ContainerBuilder();
+ $container->registerForAutoconfiguration('AInterface');
+ $config->registerForAutoconfiguration('AInterface');
+ $container->merge($config);
}
public function testResolveEnvValues()
@@ -1097,6 +1117,17 @@ public function testServiceLocator()
$this->assertInstanceOf(ServiceLocator::class, $foo = $container->get('foo_service'));
$this->assertSame($container->get('bar_service'), $foo->get('bar'));
}
+
+ public function testRegisterForAutoconfiguration()
+ {
+ $container = new ContainerBuilder();
+ $childDefA = $container->registerForAutoconfiguration('AInterface');
+ $childDefB = $container->registerForAutoconfiguration('BInterface');
+ $this->assertSame(array('AInterface' => $childDefA, 'BInterface' => $childDefB), $container->getAutomaticInstanceofDefinitions());
+
+ // when called multiple times, the same instance is returned
+ $this->assertSame($childDefA, $container->registerForAutoconfiguration('AInterface'));
+ }
}
class FooClass
diff --git a/src/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php b/src/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php
index 797c8cc0feb13..2821dc17c0dc2 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php
@@ -344,6 +344,7 @@ public function testGetChangesWithChanges()
$def->addTag('foo_tag');
$def->addMethodCall('methodCall');
$def->setProperty('fooprop', true);
+ $def->setAutoconfigured(true);
$this->assertSame(array(
'class' => true,
@@ -356,6 +357,7 @@ public function testGetChangesWithChanges()
'lazy' => true,
'public' => true,
'shared' => true,
+ 'autoconfigured' => true,
), $def->getChanges());
$def->setChanges(array());
@@ -377,4 +379,12 @@ public function testTypes()
$this->assertSame($def, $def->removeAutowiringType('Foo'));
$this->assertEquals(array('Bar'), $def->getAutowiringTypes());
}
+
+ public function testShouldAutoconfigure()
+ {
+ $def = new Definition('stdClass');
+ $this->assertFalse($def->isAutoconfigured());
+ $def->setAutoconfigured(true);
+ $this->assertTrue($def->isAutoconfigured());
+ }
}
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_autoconfigure.xml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_autoconfigure.xml
new file mode 100644
index 0000000000000..5e855c097288e
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_autoconfigure.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_autoconfigure.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_autoconfigure.yml
new file mode 100644
index 0000000000000..809c9f47ddfda
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_autoconfigure.yml
@@ -0,0 +1,9 @@
+
+services:
+ _defaults:
+ autoconfigure: true
+
+ use_defaults_settings: ~
+
+ override_defaults_settings_to_false:
+ autoconfigure: false
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_defaults_instanceof_parent.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_defaults_instanceof_parent.yml
index 838e0626e7dbd..9e332a8405b0b 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_defaults_instanceof_parent.yml
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_defaults_instanceof_parent.yml
@@ -1,11 +1,13 @@
services:
_defaults:
autowire: true
+ autoconfigure: true
_instanceof:
Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStubParent:
# should override _defaults
autowire: false
+ autoconfigure: false
shared: false
tags:
- { name: foo_tag, tag_option: from_instanceof }
@@ -30,6 +32,7 @@ services:
class: Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStub
# override instanceof
autowire: true
+ autoconfigure: true
parent_service:
abstract: true
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php
index 8b628b098798a..5d9732119515b 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php
@@ -693,6 +693,16 @@ public function testInstanceof()
$this->assertTrue($definition->isLazy());
$this->assertSame(array('foo' => array(array()), 'bar' => array(array())), $definition->getTags());
}
+
+ public function testAutoConfigureInstanceof()
+ {
+ $container = new ContainerBuilder();
+ $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
+ $loader->load('services_autoconfigure.xml');
+
+ $this->assertTrue($container->getDefinition('use_defaults_settings')->isAutoconfigured());
+ $this->assertFalse($container->getDefinition('override_defaults_settings_to_false')->isAutoconfigured());
+ }
}
interface BarInterface
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php
index 8f628ae3e22cb..c0cf1e82cf78e 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php
@@ -567,6 +567,16 @@ public function testAnonymousServicesInParameters()
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
$loader->load('anonymous_services_in_parameters.yml');
}
+
+ public function testAutoConfigureInstanceof()
+ {
+ $container = new ContainerBuilder();
+ $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
+ $loader->load('services_autoconfigure.yml');
+
+ $this->assertTrue($container->getDefinition('use_defaults_settings')->isAutoconfigured());
+ $this->assertFalse($container->getDefinition('override_defaults_settings_to_false')->isAutoconfigured());
+ }
}
interface FooInterface