diff --git a/core/core.services.yml b/core/core.services.yml
index 53a2725..7793bc8 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -779,8 +779,7 @@ services:
       - { name: route_filter }
   paramconverter_manager:
     class: Drupal\Core\ParamConverter\ParamConverterManager
-    tags:
-      - { name: service_collector, tag: paramconverter, call: addConverter }
+    parent: container.trait
   paramconverter_subscriber:
     class: Drupal\Core\EventSubscriber\ParamConverterSubscriber
     tags:
diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php
index 75d8ec5..1592a16 100644
--- a/core/lib/Drupal/Core/CoreServiceProvider.php
+++ b/core/lib/Drupal/Core/CoreServiceProvider.php
@@ -13,6 +13,7 @@
 use Drupal\Core\DependencyInjection\Compiler\RegisterLazyRouteEnhancers;
 use Drupal\Core\DependencyInjection\Compiler\RegisterLazyRouteFilters;
 use Drupal\Core\DependencyInjection\Compiler\DependencySerializationTraitPass;
+use Drupal\Core\DependencyInjection\Compiler\RegisterParamConverters;
 use Drupal\Core\DependencyInjection\Compiler\StackedKernelPass;
 use Drupal\Core\DependencyInjection\Compiler\StackedSessionHandlerPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterStreamWrappersPass;
@@ -78,6 +79,7 @@ public function register(ContainerBuilder $container) {
     $container->addCompilerPass(new RegisterAccessChecksPass());
     $container->addCompilerPass(new RegisterLazyRouteEnhancers());
     $container->addCompilerPass(new RegisterLazyRouteFilters());
+    $container->addCompilerPass(new RegisterParamConverters());
 
     // Add a compiler pass for registering services needing destruction.
     $container->addCompilerPass(new RegisterServicesForDestructionPass());
diff --git a/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterParamConverters.php b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterParamConverters.php
new file mode 100644
index 0000000..049ac81
--- /dev/null
+++ b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterParamConverters.php
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\DependencyInjection\Compiler\RegisterParamConverters.
+ */
+
+namespace Drupal\Core\DependencyInjection\Compiler;
+
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+
+/**
+ * Registers all param converters for the param converter manager.
+ */
+class RegisterParamConverters implements CompilerPassInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function process(ContainerBuilder $container) {
+    if (!$container->hasDefinition('paramconverter_manager')) {
+      return;
+    }
+
+    $service_ids = [];
+
+    foreach ($container->findTaggedServiceIds('paramconverter') as $id => $attributes) {
+      $service_ids[$id] = $id;
+    }
+
+    $container->getDefinition('paramconverter_manager')
+      ->addArgument($service_ids);
+  }
+
+}
diff --git a/core/lib/Drupal/Core/ParamConverter/ParamConverterManager.php b/core/lib/Drupal/Core/ParamConverter/ParamConverterManager.php
index 8719cd9..b6808ce 100644
--- a/core/lib/Drupal/Core/ParamConverter/ParamConverterManager.php
+++ b/core/lib/Drupal/Core/ParamConverter/ParamConverterManager.php
@@ -18,7 +18,16 @@
  * A typical use case for this would be upcasting (converting) a node id to a
  * node entity.
  */
-class ParamConverterManager implements ParamConverterManagerInterface {
+class ParamConverterManager implements ParamConverterManagerInterface, ContainerAwareInterface {
+
+  use ContainerAwareTrait;
+
+  /**
+   * IDs of all param converter services.
+   *
+   * @var string[]
+   */
+  protected $serviceIds;
 
   /**
    * Array of loaded converter services keyed by their ids.
@@ -28,22 +37,27 @@ class ParamConverterManager implements ParamConverterManagerInterface {
   protected $converters = array();
 
   /**
-   * {@inheritdoc}
+   * Constructs a new ParamConverterManager object.
+   *
+   * @param string[] $service_ids
+   *   IDs of all param converter services to use.
    */
-  public function addConverter(ParamConverterInterface $param_converter, $id) {
-    $this->converters[$id] = $param_converter;
-    return $this;
+  function __construct(array $service_ids) {
+    $this->serviceIds = $service_ids;
   }
 
   /**
    * {@inheritdoc}
    */
-  public function getConverter($converter) {
-    if (isset($this->converters[$converter])) {
-      return $this->converters[$converter];
+  public function getConverter($id) {
+    if (isset($this->converters[$id])) {
+      return $this->converters[$id];
+    }
+    elseif ($converter = $this->container->get($id)) {
+      return $this->converters[$id] = $converter;
     }
     else {
-      throw new \InvalidArgumentException(sprintf('No converter has been registered for %s', $converter));
+      throw new \InvalidArgumentException(sprintf('No converter has been registered for %s', $id));
     }
   }
 
@@ -64,7 +78,7 @@ public function setRouteParameterConverters(RouteCollection $routes) {
           continue;
         }
 
-        foreach (array_keys($this->converters) as $converter) {
+        foreach ($this->serviceIds as $converter) {
           if ($this->getConverter($converter)->applies($definition, $name, $route)) {
             $definition['converter'] = $converter;
             break;
diff --git a/core/lib/Drupal/Core/ParamConverter/ParamConverterManagerInterface.php b/core/lib/Drupal/Core/ParamConverter/ParamConverterManagerInterface.php
index 77f69c5..d3668c8 100644
--- a/core/lib/Drupal/Core/ParamConverter/ParamConverterManagerInterface.php
+++ b/core/lib/Drupal/Core/ParamConverter/ParamConverterManagerInterface.php
@@ -15,18 +15,6 @@
 interface ParamConverterManagerInterface {
 
   /**
-   * Registers a parameter converter with the manager.
-   *
-   * @param \Drupal\Core\ParamConverter\ParamConverterInterface $param_converter
-   *   The added param converter instance.
-   * @param string $id
-   *   The parameter converter service id to register.
-   *
-   * @return $this
-   */
-  public function addConverter(ParamConverterInterface $param_converter, $id);
-
-  /**
    * Lazy-loads converter services.
    *
    * @param string $id
diff --git a/core/tests/Drupal/Tests/Core/ParamConverter/ParamConverterManagerTest.php b/core/tests/Drupal/Tests/Core/ParamConverter/ParamConverterManagerTest.php
index dc0f3cc..be5ec2b 100644
--- a/core/tests/Drupal/Tests/Core/ParamConverter/ParamConverterManagerTest.php
+++ b/core/tests/Drupal/Tests/Core/ParamConverter/ParamConverterManagerTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Tests\Core\ParamConverter;
 
+use Drupal\Core\DependencyInjection\Container;
 use Drupal\Core\ParamConverter\ParamConverterManager;
 use Drupal\Tests\UnitTestCase;
 use Symfony\Cmf\Component\Routing\RouteObjectInterface;
@@ -20,17 +21,25 @@
 class ParamConverterManagerTest extends UnitTestCase {
 
   /**
-   * @var \Drupal\Core\ParamConverter\ParamConverterManager
-   */
-  protected $manager;
-
-  /**
-   * {@inheritdoc}
+   * Creates a new param converter manager with the specified converters.
+   *
+   * @param array $converters
+   *   An associative array of of param converter services that the manager
+   *   should be aware of, keyed by service IDs.
+   *
+   * @return \Drupal\Core\ParamConverter\ParamConverterManager
+   *   The created manager.
    */
-  protected function setUp() {
-    parent::setUp();
-
-    $this->manager = new ParamConverterManager();
+  protected function createParamConverterManager(array $converters) {
+    // Create a container with the converter services.
+    $container = new Container();
+    foreach ($converters as $name => $converter) {
+      $container->set($name, $converter);
+    }
+    // Create a converter manager with the converter service IDs.
+    $manager = new ParamConverterManager(array_keys($converters));
+    $manager->setContainer($container);
+    return $manager;
   }
 
   /**
@@ -45,11 +54,11 @@ public function testGetConverter($name, $class) {
       ->setMockClassName($class)
       ->getMock();
 
-    $this->manager->addConverter($converter, $name);
+    $manager = $this->createParamConverterManager([$name => $converter]);
 
-    $this->assertInstanceOf($class, $this->manager->getConverter($name));
+    $this->assertInstanceOf($class, $manager->getConverter($name));
     // Assert that a second call to getConverter() does not use the container.
-    $this->assertInstanceOf($class, $this->manager->getConverter($name));
+    $this->assertInstanceOf($class, $manager->getConverter($name));
   }
 
   /**
@@ -60,7 +69,7 @@ public function testGetConverter($name, $class) {
    * @expectedException \InvalidArgumentException
    */
   public function testGetConverterException() {
-    $this->manager->getConverter('undefined.converter');
+    $this->createParamConverterManager(array())->getConverter('undefined.converter');
   }
 
   /**
@@ -138,7 +147,7 @@ public function testSetRouteParameterConverters($path, $parameters = NULL, $expe
       ->method('applies')
       ->with($this->anything(), 'id', $this->anything())
       ->will($this->returnValue(TRUE));
-    $this->manager->addConverter($converter, 'applied');
+    $manager = $this->createParamConverterManager(['applied' => $converter]);
 
     $route = new Route($path);
     if ($parameters) {
@@ -147,7 +156,7 @@ public function testSetRouteParameterConverters($path, $parameters = NULL, $expe
     $collection = new RouteCollection();
     $collection->add('test_route', $route);
 
-    $this->manager->setRouteParameterConverters($collection);
+    $manager->setRouteParameterConverters($collection);
     foreach ($collection as $route) {
       $result = $route->getOption('parameters');
       if ($expected) {
@@ -200,9 +209,9 @@ public function testConvert() {
       ->method('convert')
       ->with(1, $this->isType('array'), 'id', $this->isType('array'))
       ->will($this->returnValue('something_better!'));
-    $this->manager->addConverter($converter, 'test_convert');
+    $manager = $this->createParamConverterManager(['test_convert' => $converter]);
 
-    $result = $this->manager->convert($defaults);
+    $result = $manager->convert($defaults);
 
     $this->assertEquals($expected, $result);
   }
@@ -219,7 +228,7 @@ public function testConvertNoConverting() {
 
     $expected = $defaults;
 
-    $result = $this->manager->convert($defaults);
+    $result = $this->createParamConverterManager(array())->convert($defaults);
     $this->assertEquals($expected, $result);
   }
 
@@ -249,9 +258,9 @@ public function testConvertMissingParam() {
       ->method('convert')
       ->with(1, $this->isType('array'), 'id', $this->isType('array'))
       ->will($this->returnValue(NULL));
-    $this->manager->addConverter($converter, 'test_convert');
+    $manager = $this->createParamConverterManager(['test_convert' => $converter]);
 
-    $this->manager->convert($defaults);
+    $manager->convert($defaults);
   }
 
 }
