diff --git a/core/core.services.yml b/core/core.services.yml
index 0b18c3b..604888e 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -1034,18 +1034,18 @@ services:
       - { name: render.main_content_renderer, format: html }
   main_content_renderer.ajax:
     class: Drupal\Core\Render\MainContent\AjaxRenderer
-    arguments: ['@element_info']
+    arguments: ['@element_info', '@renderer']
     tags:
       - { name: render.main_content_renderer, format: drupal_ajax }
       - { name: render.main_content_renderer, format: iframeupload }
   main_content_renderer.dialog:
     class: Drupal\Core\Render\MainContent\DialogRenderer
-    arguments: ['@title_resolver']
+    arguments: ['@title_resolver', '@renderer']
     tags:
       - { name: render.main_content_renderer, format: drupal_dialog }
   main_content_renderer.modal:
     class: Drupal\Core\Render\MainContent\ModalRenderer
-    arguments: ['@title_resolver']
+    arguments: ['@title_resolver', '@renderer']
     tags:
       - { name: render.main_content_renderer, format: drupal_modal }
   controller.form:
diff --git a/core/lib/Drupal/Core/Render/MainContent/AjaxRenderer.php b/core/lib/Drupal/Core/Render/MainContent/AjaxRenderer.php
index 0a1b993..fb82e11 100644
--- a/core/lib/Drupal/Core/Render/MainContent/AjaxRenderer.php
+++ b/core/lib/Drupal/Core/Render/MainContent/AjaxRenderer.php
@@ -7,6 +7,7 @@
 use Drupal\Core\Ajax\InsertCommand;
 use Drupal\Core\Ajax\PrependCommand;
 use Drupal\Core\Render\ElementInfoManagerInterface;
+use Drupal\Core\Render\RendererInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Symfony\Component\HttpFoundation\Request;
 
@@ -30,13 +31,23 @@ class AjaxRenderer implements MainContentRendererInterface {
   protected $elementInfoManager;
 
   /**
+   * The renderer.
+   *
+   * @var \Drupal\Core\Render\RendererInterface
+   */
+  protected $renderer;
+
+  /**
    * Constructs a new AjaxRenderer instance.
    *
    * @param \Drupal\Core\Render\ElementInfoManagerInterface $element_info_manager
    *   The element info manager.
+   * @param \Drupal\Core\Render\RendererInterface $renderer
+   *   The renderer.
    */
-  public function __construct(ElementInfoManagerInterface $element_info_manager) {
+  public function __construct(ElementInfoManagerInterface $element_info_manager, RendererInterface $renderer) {
     $this->elementInfoManager = $element_info_manager;
+    $this->renderer = $renderer;
   }
 
   /**
@@ -75,12 +86,13 @@ public function renderResponse(array $main_content, Request $request, RouteMatch
   }
 
   /**
-   * Wraps drupal_render_root().
+   * Wraps renderRoot().
    *
-   * @todo Remove as part of https://www.drupal.org/node/2182149.
+   * @deprecated as of Drupal 8.3.x, will be removed before Drupal 9.0.0. Use
+   *   $this->renderer or the 'renderer' service instead.
    */
   protected function drupalRenderRoot(&$elements) {
-    return drupal_render_root($elements);
+    return $this->renderer->renderRoot($elements);
   }
 
 }
diff --git a/core/lib/Drupal/Core/Render/MainContent/DialogRenderer.php b/core/lib/Drupal/Core/Render/MainContent/DialogRenderer.php
index c71604b..23478f4 100644
--- a/core/lib/Drupal/Core/Render/MainContent/DialogRenderer.php
+++ b/core/lib/Drupal/Core/Render/MainContent/DialogRenderer.php
@@ -7,6 +7,7 @@
 use Drupal\Core\Ajax\OpenDialogCommand;
 use Drupal\Core\Controller\TitleResolverInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\Core\Render\RendererInterface;
 use Symfony\Component\HttpFoundation\Request;
 
 /**
@@ -22,13 +23,23 @@ class DialogRenderer implements MainContentRendererInterface {
   protected $titleResolver;
 
   /**
+   * The renderer.
+   *
+   * @var \Drupal\Core\Render\RendererInterface
+   */
+  protected $renderer;
+
+  /**
    * Constructs a new DialogRenderer.
    *
    * @param \Drupal\Core\Controller\TitleResolverInterface $title_resolver
    *   The title resolver.
+   * @param \Drupal\Core\Render\RendererInterface $renderer
+   *   The renderer.
    */
-  public function __construct(TitleResolverInterface $title_resolver) {
+  public function __construct(TitleResolverInterface $title_resolver, RendererInterface $renderer) {
     $this->titleResolver = $title_resolver;
+    $this->renderer = $renderer;
   }
 
   /**
@@ -38,7 +49,7 @@ public function renderResponse(array $main_content, Request $request, RouteMatch
     $response = new AjaxResponse();
 
     // First render the main content, because it might provide a title.
-    $content = drupal_render_root($main_content);
+    $content = $this->renderer->renderRoot($main_content);
 
     // Attach the library necessary for using the OpenDialogCommand and set the
     // attachments for this Ajax response.
diff --git a/core/lib/Drupal/Core/Render/MainContent/ModalRenderer.php b/core/lib/Drupal/Core/Render/MainContent/ModalRenderer.php
index fcb38e2..bf407a4 100644
--- a/core/lib/Drupal/Core/Render/MainContent/ModalRenderer.php
+++ b/core/lib/Drupal/Core/Render/MainContent/ModalRenderer.php
@@ -6,6 +6,7 @@
 use Drupal\Core\Ajax\OpenModalDialogCommand;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Symfony\Component\HttpFoundation\Request;
+use Drupal\Core\Render\RendererInterface;
 
 /**
  * Default main content renderer for modal dialog requests.
@@ -13,13 +14,33 @@
 class ModalRenderer extends DialogRenderer {
 
   /**
+   * The renderer.
+   *
+   * @var \Drupal\Core\Render\RendererInterface
+   */
+  protected $renderer;
+
+  /**
+   * Constructs a new ModalRenderer.
+   *
+   * @param \Drupal\Core\Controller\TitleResolverInterface $title_resolver
+   *   The title resolver.
+   * @param \Drupal\Core\Render\RendererInterface $renderer
+   *   The renderer.
+   */
+  public function __construct(TitleResolverInterface $title_resolver, RendererInterface $renderer) {
+    parent::__construct($title_resolver);
+    $this->renderer = $renderer;
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function renderResponse(array $main_content, Request $request, RouteMatchInterface $route_match) {
     $response = new AjaxResponse();
 
     // First render the main content, because it might provide a title.
-    $content = drupal_render_root($main_content);
+    $content = $this->renderer->renderRoot($main_content);
 
     // Attach the library necessary for using the OpenModalDialogCommand and set
     // the attachments for this Ajax response.
diff --git a/core/modules/filter/tests/src/Kernel/FilterAPITest.php b/core/modules/filter/tests/src/Kernel/FilterAPITest.php
index 50189a6..9d028cf 100644
--- a/core/modules/filter/tests/src/Kernel/FilterAPITest.php
+++ b/core/modules/filter/tests/src/Kernel/FilterAPITest.php
@@ -21,10 +21,18 @@ class FilterAPITest extends EntityKernelTestBase {
 
   public static $modules = array('system', 'filter', 'filter_test', 'user');
 
+  /**
+   * The renderer.
+   *
+   * @var \Drupal\Core\Render\RendererInterface
+   */
+  protected $renderer;
+
   protected function setUp() {
     parent::setUp();
 
     $this->installConfig(array('system', 'filter', 'filter_test'));
+    $this->renderer = $this->container->get('renderer');
   }
 
   /**
@@ -288,7 +296,7 @@ function testProcessedTextElement() {
       '#text' => '<p>Hello, world!</p>',
       '#format' => 'element_test',
     );
-    drupal_render_root($build);
+    $this->renderer->renderRoot($build);
 
     // Verify the attachments and cacheability metadata.
     $expected_attachments = array(
diff --git a/core/modules/rest/src/Tests/Views/StyleSerializerTest.php b/core/modules/rest/src/Tests/Views/StyleSerializerTest.php
index 4c004fc..54d2dbb 100644
--- a/core/modules/rest/src/Tests/Views/StyleSerializerTest.php
+++ b/core/modules/rest/src/Tests/Views/StyleSerializerTest.php
@@ -54,6 +54,13 @@ class StyleSerializerTest extends PluginTestBase {
    */
   protected $adminUser;
 
+  /**
+   * The renderer.
+   *
+   * @var \Drupal\Core\Render\RendererInterface
+   */
+  protected $renderer;
+
   protected function setUp() {
     parent::setUp();
 
@@ -67,6 +74,7 @@ protected function setUp() {
     }
 
     $this->enableViewsTestModule();
+    $this->renderer = $this->container->get('renderer');
   }
 
   /**
@@ -140,7 +148,7 @@ public function testSerializerResponses() {
     // Mock the request content type by setting it on the display handler.
     $view->display_handler->setContentType('json');
     $output = $view->preview();
-    $this->assertIdentical($actual_json, (string) drupal_render_root($output), 'The expected JSON preview output was found.');
+    $this->assertIdentical($actual_json, (string) $this->renderer->renderRoot($output), 'The expected JSON preview output was found.');
 
     // Test a 403 callback.
     $this->drupalGet('test/serialize/denied');
@@ -682,8 +690,6 @@ public function testFieldapiField() {
    * Tests the "Grouped rows" functionality.
    */
   public function testGroupRows() {
-    /** @var \Drupal\Core\Render\RendererInterface $renderer */
-    $renderer = $this->container->get('renderer');
     $this->drupalCreateContentType(['type' => 'page']);
     // Create a text field with cardinality set to unlimited.
     $field_name = 'field_group_rows';
@@ -726,7 +732,7 @@ public function testGroupRows() {
     // Check if the field_group_rows field is grouped.
     $expected = [];
     $expected[] = [$field_name => implode(', ', $grouped_field_values)];
-    $this->assertEqual($serializer->serialize($expected, 'json'), (string) $renderer->renderRoot($build));
+    $this->assertEqual($serializer->serialize($expected, 'json'), (string) $this->renderer->renderRoot($build));
     // Set the group rows setting to false.
     $view = Views::getView('test_serializer_node_display_field');
     $view->setDisplay('rest_export_1');
@@ -738,7 +744,7 @@ public function testGroupRows() {
     foreach ($grouped_field_values as $grouped_field_value) {
       $expected[] = [$field_name => $grouped_field_value];
     }
-    $this->assertEqual($serializer->serialize($expected, 'json'), (string) $renderer->renderRoot($build));
+    $this->assertEqual($serializer->serialize($expected, 'json'), (string) $this->renderer->renderRoot($build));
   }
 
   /**
diff --git a/core/modules/system/src/Tests/Common/RenderWebTest.php b/core/modules/system/src/Tests/Common/RenderWebTest.php
index fde7fa6..2bfd59a 100644
--- a/core/modules/system/src/Tests/Common/RenderWebTest.php
+++ b/core/modules/system/src/Tests/Common/RenderWebTest.php
@@ -22,6 +22,22 @@ class RenderWebTest extends WebTestBase {
   public static $modules = array('common_test');
 
   /**
+   * The renderer.
+   *
+   * @var \Drupal\Core\Render\RendererInterface
+   */
+  protected $renderer;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->renderer = $this->container->get('renderer');
+  }
+
+
+  /**
    * Asserts the cache context for the wrapper format is always present.
    */
   function testWrapperFormatCacheContext() {
@@ -163,7 +179,7 @@ function testDrupalRenderFormElements() {
    */
   protected function assertRenderedElement(array $element, $xpath, array $xpath_args = array()) {
     $original_element = $element;
-    $this->setRawContent(drupal_render_root($element));
+    $this->setRawContent($this->renderer->renderRoot($element));
     $this->verbose('<hr />' . $this->getRawContent());
 
     // @see \Drupal\simpletest\WebTestBase::xpath()
diff --git a/core/modules/views/src/Plugin/views/display/Feed.php b/core/modules/views/src/Plugin/views/display/Feed.php
index bd59091..6576049 100644
--- a/core/modules/views/src/Plugin/views/display/Feed.php
+++ b/core/modules/views/src/Plugin/views/display/Feed.php
@@ -5,8 +5,12 @@
 use Drupal\Core\Cache\CacheableMetadata;
 use Drupal\Core\Cache\CacheableResponse;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Render\RendererInterface;
+use Drupal\Core\Routing\RouteProviderInterface;
+use Drupal\Core\State\StateInterface;
 use Drupal\views\ViewExecutable;
 use Drupal\views\Views;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
 
 /**
@@ -40,6 +44,48 @@ class Feed extends PathPluginBase implements ResponseDisplayPluginInterface {
   protected $usesPager = FALSE;
 
   /**
+   * The renderer.
+   *
+   * @var \Drupal\Core\Render\RendererInterface
+   */
+  protected $renderer;
+
+  /**
+   * Constructs a PathPluginBase object.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Routing\RouteProviderInterface $route_provider
+   *   The route provider.
+   * @param \Drupal\Core\State\StateInterface $state
+   *   The state key value store.
+   * @param \Drupal\Core\Render\RendererInterface $renderer
+   *   The renderer.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, RouteProviderInterface $route_provider, StateInterface $state, RendererInterface $renderer) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition, $route_provider, $state);
+    $this->renderer = $renderer;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('router.route_provider'),
+      $container->get('state'),
+      $container->get('renderer')
+    );
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function getType() {
@@ -92,7 +138,7 @@ public function preview() {
     if (!empty($this->view->live_preview)) {
       $output = array(
         '#prefix' => '<pre>',
-        '#plain_text' => drupal_render_root($output),
+        '#plain_text' => $this->renderer->renderRoot($output),
         '#suffix' => '</pre>',
       );
     }
