diff --git a/core/core.services.yml b/core/core.services.yml
index cb935793a6b0b17d9e7bcc90b970d4b006036b0d..5e6e2d9a80a9c36a3b82ae2f86e014b618c96f10 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -1553,13 +1553,9 @@ services:
       - { name: service_collector, tag: 'twig.extension', call: addExtension }
   twig.extension:
     class: Drupal\Core\Template\TwigExtension
-    arguments: ['@renderer']
+    arguments: ['@renderer', '@url_generator', '@theme.manager', '@date.formatter']
     tags:
       - { name: twig.extension, priority: 100 }
-    calls:
-      - [setUrlGenerator, ['@url_generator']]
-      - [setThemeManager, ['@theme.manager']]
-      - [setDateFormatter, ['@date.formatter']]
   # @todo Figure out what to do about debugging functions.
   # @see https://www.drupal.org/node/1804998
   twig.extension.debug:
diff --git a/core/lib/Drupal/Core/Template/TwigExtension.php b/core/lib/Drupal/Core/Template/TwigExtension.php
index 3fcbe2c86f37bde6687a0e1dfc838927b48e3093..7d67ff991c4cb6779ab7067dec151ffc95af4fa8 100644
--- a/core/lib/Drupal/Core/Template/TwigExtension.php
+++ b/core/lib/Drupal/Core/Template/TwigExtension.php
@@ -58,9 +58,18 @@ class TwigExtension extends \Twig_Extension {
    *
    * @param \Drupal\Core\Render\RendererInterface $renderer
    *   The renderer.
+   * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
+   *   The URL generator.
+   * @param \Drupal\Core\Theme\ThemeManagerInterface $theme_manager
+   *   The theme manager.
+   * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
+   *   The date formatter.
    */
-  public function __construct(RendererInterface $renderer) {
+  public function __construct(RendererInterface $renderer, UrlGeneratorInterface $url_generator, ThemeManagerInterface $theme_manager, DateFormatterInterface $date_formatter) {
     $this->renderer = $renderer;
+    $this->urlGenerator = $url_generator;
+    $this->themeManager = $theme_manager;
+    $this->dateFormatter = $date_formatter;
   }
 
   /**
@@ -72,7 +81,6 @@ public function __construct(RendererInterface $renderer) {
    * @return $this
    *
    * @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0.
-   *   Use \Drupal\Core\Template\TwigExtension::setUrlGenerator().
    */
   public function setGenerators(UrlGeneratorInterface $url_generator) {
     return $this->setUrlGenerator($url_generator);
@@ -85,6 +93,8 @@ public function setGenerators(UrlGeneratorInterface $url_generator) {
    *   The URL generator.
    *
    * @return $this
+   *
+   * @deprecated in Drupal 8.3.x-dev, will be removed before Drupal 9.0.0.
    */
   public function setUrlGenerator(UrlGeneratorInterface $url_generator) {
     $this->urlGenerator = $url_generator;
@@ -98,6 +108,8 @@ public function setUrlGenerator(UrlGeneratorInterface $url_generator) {
    *   The theme manager.
    *
    * @return $this
+   *
+   * @deprecated in Drupal 8.3.x-dev, will be removed before Drupal 9.0.0.
    */
   public function setThemeManager(ThemeManagerInterface $theme_manager) {
     $this->themeManager = $theme_manager;
@@ -111,6 +123,8 @@ public function setThemeManager(ThemeManagerInterface $theme_manager) {
    *   The date formatter.
    *
    * @return $this
+   *
+   * @deprecated in Drupal 8.3.x-dev, will be removed before Drupal 9.0.0.
    */
   public function setDateFormatter(DateFormatterInterface $date_formatter) {
     $this->dateFormatter = $date_formatter;
diff --git a/core/modules/system/tests/modules/twig_extension_test/src/TwigExtension/TestExtension.php b/core/modules/system/tests/modules/twig_extension_test/src/TwigExtension/TestExtension.php
index 4afa3a78cbdd83774eeefba530789640898c6779..78d10202882fa72606819c0b7d7e1730749a8f7e 100644
--- a/core/modules/system/tests/modules/twig_extension_test/src/TwigExtension/TestExtension.php
+++ b/core/modules/system/tests/modules/twig_extension_test/src/TwigExtension/TestExtension.php
@@ -2,12 +2,11 @@
 
 namespace Drupal\twig_extension_test\TwigExtension;
 
-use Drupal\Core\Template\TwigExtension;
 
 /**
  * A test Twig extension that adds a custom function and a custom filter.
  */
-class TestExtension extends TwigExtension {
+class TestExtension extends \Twig_Extension {
 
   /**
    * Generates a list of all Twig functions that this extension defines.
diff --git a/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php b/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php
index 38373aa0673979b7e745206e40646c3bc188e9b1..396b2f9765ff9ce4ed5e68f936b9959e08e1c3a8 100644
--- a/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php
+++ b/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php
@@ -1,16 +1,9 @@
 <?php
 
-/**
- * @file
- * Contains \Drupal\Tests\Core\Template\TwigExtensionTest.
- */
-
 namespace Drupal\Tests\Core\Template;
 
 use Drupal\Core\GeneratedLink;
 use Drupal\Core\Render\RenderableInterface;
-use Drupal\Core\Render\RendererInterface;
-use Drupal\Core\Routing\UrlGeneratorInterface;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\Core\Template\Loader\StringLoader;
 use Drupal\Core\Template\TwigEnvironment;
@@ -26,26 +19,74 @@
  */
 class TwigExtensionTest extends UnitTestCase {
 
+  /**
+   * The renderer.
+   *
+   * @var \Drupal\Core\Render\RendererInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $renderer;
+
+  /**
+   * The url generator.
+   *
+   * @var \Drupal\Core\Routing\UrlGeneratorInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $urlGenerator;
+
+  /**
+   * The theme manager.
+   *
+   * @var \Drupal\Core\Theme\ThemeManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $themeManager;
+
+  /**
+   * The date formatter.
+   *
+   * @var \Drupal\Core\Datetime\DateFormatterInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $dateFormatter;
+
+  /**
+   * The system under test.
+   *
+   * @var \Drupal\Core\Template\TwigExtension
+   */
+  protected $systemUnderTest;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+
+    $this->renderer = $this->getMock('\Drupal\Core\Render\RendererInterface');
+    $this->urlGenerator = $this->getMock('\Drupal\Core\Routing\UrlGeneratorInterface');
+    $this->themeManager = $this->getMock('\Drupal\Core\Theme\ThemeManagerInterface');
+    $this->dateFormatter = $this->getMock('\Drupal\Core\Datetime\DateFormatterInterface');
+
+    $this->systemUnderTest = new TwigExtension($this->renderer, $this->urlGenerator, $this->themeManager, $this->dateFormatter);
+  }
+
   /**
    * Tests the escaping
    *
    * @dataProvider providerTestEscaping
    */
   public function testEscaping($template, $expected) {
-    $renderer = $this->getMock('\Drupal\Core\Render\RendererInterface');
     $twig = new \Twig_Environment(NULL, array(
       'debug' => TRUE,
       'cache' => FALSE,
       'autoescape' => 'html',
-      'optimizations' => 0
+      'optimizations' => 0,
     ));
-    $twig->addExtension((new TwigExtension($renderer))->setUrlGenerator($this->getMock('Drupal\Core\Routing\UrlGeneratorInterface')));
+    $twig->addExtension($this->systemUnderTest);
 
     $nodes = $twig->parse($twig->tokenize($template));
 
     $this->assertSame($expected, $nodes->getNode('body')
-        ->getNode(0)
-        ->getNode('expr') instanceof \Twig_Node_Expression_Filter);
+      ->getNode(0)
+      ->getNode('expr') instanceof \Twig_Node_Expression_Filter);
   }
 
   /**
@@ -83,25 +124,19 @@ public function providerTestEscaping() {
    * Tests the active_theme function.
    */
   public function testActiveTheme() {
-    $renderer = $this->getMock('\Drupal\Core\Render\RendererInterface');
-    $extension = new TwigExtension($renderer);
-    $theme_manager = $this->getMock('\Drupal\Core\Theme\ThemeManagerInterface');
     $active_theme = $this->getMockBuilder('\Drupal\Core\Theme\ActiveTheme')
       ->disableOriginalConstructor()
       ->getMock();
-    $active_theme
-      ->expects($this->once())
+    $active_theme->expects($this->once())
       ->method('getName')
       ->willReturn('test_theme');
-    $theme_manager
-      ->expects($this->once())
+    $this->themeManager->expects($this->once())
       ->method('getActiveTheme')
       ->willReturn($active_theme);
-    $extension->setThemeManager($theme_manager);
 
     $loader = new \Twig_Loader_String();
     $twig = new \Twig_Environment($loader);
-    $twig->addExtension($extension);
+    $twig->addExtension($this->systemUnderTest);
     $result = $twig->render('{{ active_theme() }}');
     $this->assertEquals('test_theme', $result);
   }
@@ -110,30 +145,21 @@ public function testActiveTheme() {
    * Tests the format_date filter.
    */
   public function testFormatDate() {
-    $date_formatter = $this->getMockBuilder('\Drupal\Core\Datetime\DateFormatter')
-      ->disableOriginalConstructor()
-      ->getMock();
-    $date_formatter->expects($this->exactly(2))
+    $this->dateFormatter->expects($this->exactly(2))
       ->method('format')
       ->willReturn('1978-11-19');
-    $renderer = $this->getMock('\Drupal\Core\Render\RendererInterface');
-    $extension = new TwigExtension($renderer);
-    $extension->setDateFormatter($date_formatter);
 
     $loader = new StringLoader();
     $twig = new \Twig_Environment($loader);
-    $twig->addExtension($extension);
+    $twig->addExtension($this->systemUnderTest);
     $result = $twig->render('{{ time|format_date("html_date") }}');
-    $this->assertEquals($date_formatter->format('html_date'), $result);
+    $this->assertEquals($this->dateFormatter->format('html_date'), $result);
   }
 
   /**
    * Tests the active_theme_path function.
    */
   public function testActiveThemePath() {
-    $renderer = $this->getMock('\Drupal\Core\Render\RendererInterface');
-    $extension = new TwigExtension($renderer);
-    $theme_manager = $this->getMock('\Drupal\Core\Theme\ThemeManagerInterface');
     $active_theme = $this->getMockBuilder('\Drupal\Core\Theme\ActiveTheme')
       ->disableOriginalConstructor()
       ->getMock();
@@ -141,15 +167,13 @@ public function testActiveThemePath() {
       ->expects($this->once())
       ->method('getPath')
       ->willReturn('foo/bar');
-    $theme_manager
-      ->expects($this->once())
+    $this->themeManager->expects($this->once())
       ->method('getActiveTheme')
       ->willReturn($active_theme);
-    $extension->setThemeManager($theme_manager);
 
     $loader = new \Twig_Loader_String();
     $twig = new \Twig_Environment($loader);
-    $twig->addExtension($extension);
+    $twig->addExtension($this->systemUnderTest);
     $result = $twig->render('{{ active_theme_path() }}');
     $this->assertEquals('foo/bar', $result);
   }
@@ -160,34 +184,32 @@ public function testActiveThemePath() {
    * @covers ::escapeFilter
    */
   public function testSafeStringEscaping() {
-    $renderer = $this->getMock('\Drupal\Core\Render\RendererInterface');
     $twig = new \Twig_Environment(NULL, array(
       'debug' => TRUE,
       'cache' => FALSE,
       'autoescape' => 'html',
-      'optimizations' => 0
+      'optimizations' => 0,
     ));
-    $twig_extension = new TwigExtension($renderer);
 
     // By default, TwigExtension will attempt to cast objects to strings.
     // Ensure objects that implement MarkupInterface are unchanged.
     $safe_string = $this->getMock('\Drupal\Component\Render\MarkupInterface');
-    $this->assertSame($safe_string, $twig_extension->escapeFilter($twig, $safe_string, 'html', 'UTF-8', TRUE));
+    $this->assertSame($safe_string, $this->systemUnderTest->escapeFilter($twig, $safe_string, 'html', 'UTF-8', TRUE));
 
     // Ensure objects that do not implement MarkupInterface are escaped.
     $string_object = new TwigExtensionTestString("<script>alert('here');</script>");
-    $this->assertSame('&lt;script&gt;alert(&#039;here&#039;);&lt;/script&gt;', $twig_extension->escapeFilter($twig, $string_object, 'html', 'UTF-8', TRUE));
+    $this->assertSame('&lt;script&gt;alert(&#039;here&#039;);&lt;/script&gt;', $this->systemUnderTest->escapeFilter($twig, $string_object, 'html', 'UTF-8', TRUE));
   }
 
   /**
    * @covers ::safeJoin
    */
   public function testSafeJoin() {
-    $renderer = $this->prophesize(RendererInterface::class);
-    $renderer->render(['#markup' => '<strong>will be rendered</strong>', '#printed' => FALSE])->willReturn('<strong>will be rendered</strong>');
-    $renderer = $renderer->reveal();
+    $this->renderer->expects($this->any())
+      ->method('render')
+      ->with(['#markup' => '<strong>will be rendered</strong>', '#printed' => FALSE])
+      ->willReturn('<strong>will be rendered</strong>');
 
-    $twig_extension = new TwigExtension($renderer);
     $twig_environment = $this->prophesize(TwigEnvironment::class)->reveal();
 
     // Simulate t().
@@ -198,9 +220,9 @@ public function testSafeJoin() {
     $items = [
       '<em>will be escaped</em>',
       $markup,
-      ['#markup' => '<strong>will be rendered</strong>']
+      ['#markup' => '<strong>will be rendered</strong>'],
     ];
-    $result = $twig_extension->safeJoin($twig_environment, $items, '<br/>');
+    $result = $this->systemUnderTest->safeJoin($twig_environment, $items, '<br/>');
     $this->assertEquals('&lt;em&gt;will be escaped&lt;/em&gt;<br/><em>will be markup</em><br/><strong>will be rendered</strong>', $result);
 
     // Ensure safe_join Twig filter supports Traversable variables.
@@ -209,12 +231,12 @@ public function testSafeJoin() {
       $markup,
       ['#markup' => '<strong>will be rendered</strong>'],
     ]);
-    $result = $twig_extension->safeJoin($twig_environment, $items, ', ');
+    $result = $this->systemUnderTest->safeJoin($twig_environment, $items, ', ');
     $this->assertEquals('&lt;em&gt;will be escaped&lt;/em&gt;, <em>will be markup</em>, <strong>will be rendered</strong>', $result);
 
     // Ensure safe_join Twig filter supports empty variables.
     $items = NULL;
-    $result = $twig_extension->safeJoin($twig_environment, $items, '<br>');
+    $result = $this->systemUnderTest->safeJoin($twig_environment, $items, '<br>');
     $this->assertEmpty($result);
   }
 
@@ -222,13 +244,12 @@ public function testSafeJoin() {
    * @dataProvider providerTestRenderVar
    */
   public function testRenderVar($result, $input) {
-    $renderer = $this->prophesize(RendererInterface::class);
-    $renderer->render($result += ['#printed' => FALSE])->willReturn('Rendered output');
-
-    $renderer = $renderer->reveal();
-    $twig_extension = new TwigExtension($renderer);
+    $this->renderer->expects($this->any())
+      ->method('render')
+      ->with($result += ['#printed' => FALSE])
+      ->willReturn('Rendered output');
 
-    $this->assertEquals('Rendered output', $twig_extension->renderVar($input));
+    $this->assertEquals('Rendered output', $this->systemUnderTest->renderVar($input));
   }
 
   public function providerTestRenderVar() {
@@ -247,7 +268,6 @@ public function providerTestRenderVar() {
    * @covers ::bubbleArgMetadata
    */
   public function testEscapeWithGeneratedLink() {
-    $renderer = $this->prophesize(RendererInterface::class);
     $twig = new \Twig_Environment(NULL, [
         'debug' => TRUE,
         'cache' => FALSE,
@@ -256,22 +276,23 @@ public function testEscapeWithGeneratedLink() {
       ]
     );
 
-    $twig_extension = new TwigExtension($renderer->reveal());
-    $twig->addExtension($twig_extension->setUrlGenerator($this->prophesize(UrlGeneratorInterface::class)->reveal()));
+    $twig->addExtension($this->systemUnderTest);
     $link = new GeneratedLink();
     $link->setGeneratedLink('<a href="http://example.com"></a>');
     $link->addCacheTags(['foo']);
     $link->addAttachments(['library' => ['system/base']]);
 
-    $result = $twig_extension->escapeFilter($twig, $link, 'html', NULL, TRUE);
-    $renderer->render([
-      "#cache" => [
-        "contexts" => [],
-        "tags" => ["foo"],
-        "max-age" => -1
-      ],
-      "#attached" => ['library' => ['system/base']],
-    ])->shouldHaveBeenCalled();
+    $this->renderer->expects($this->atLeastOnce())
+      ->method('render')
+      ->with([
+        "#cache" => [
+          "contexts" => [],
+          "tags" => ["foo"],
+          "max-age" => -1,
+        ],
+        "#attached" => ['library' => ['system/base']],
+      ]);
+    $result = $this->systemUnderTest->escapeFilter($twig, $link, 'html', NULL, TRUE);
     $this->assertEquals('<a href="http://example.com"></a>', $result);
   }
 
@@ -280,22 +301,22 @@ public function testEscapeWithGeneratedLink() {
    * @covers ::bubbleArgMetadata
    */
   public function testRenderVarWithGeneratedLink() {
-    $renderer = $this->prophesize(RendererInterface::class);
-    $twig_extension = new TwigExtension($renderer->reveal());
     $link = new GeneratedLink();
     $link->setGeneratedLink('<a href="http://example.com"></a>');
     $link->addCacheTags(['foo']);
     $link->addAttachments(['library' => ['system/base']]);
 
-    $result = $twig_extension->renderVar($link);
-    $renderer->render([
-      "#cache" => [
-        "contexts" => [],
-        "tags" => ["foo"],
-        "max-age" => -1
-      ],
-      "#attached" => ['library' => ['system/base']],
-    ])->shouldHaveBeenCalled();
+    $this->renderer->expects($this->atLeastOnce())
+      ->method('render')
+      ->with([
+        "#cache" => [
+          "contexts" => [],
+          "tags" => ["foo"],
+          "max-age" => -1,
+        ],
+        "#attached" => ['library' => ['system/base']],
+      ]);
+    $result = $this->systemUnderTest->renderVar($link);
     $this->assertEquals('<a href="http://example.com"></a>', $result);
   }
 
@@ -305,11 +326,9 @@ public function testRenderVarWithGeneratedLink() {
    * @covers ::createAttribute
    */
   public function testCreateAttribute() {
-    $renderer = $this->prophesize(RendererInterface::class);
-    $extension = new TwigExtension($renderer->reveal());
     $loader = new StringLoader();
     $twig = new \Twig_Environment($loader);
-    $twig->addExtension($extension);
+    $twig->addExtension($this->systemUnderTest);
 
     $iterations = [
       ['class' => ['kittens'], 'data-toggle' => 'modal', 'data-lang' => 'es'],