Inject KernelCompiler via KernelCompilerFactory (#27211)

diff --git a/packages/flutter_tools/lib/src/base/build.dart b/packages/flutter_tools/lib/src/base/build.dart
index a70cc06..29ca974 100644
--- a/packages/flutter_tools/lib/src/base/build.dart
+++ b/packages/flutter_tools/lib/src/base/build.dart
@@ -302,6 +302,7 @@
       printTrace('Extra front-end options: $extraFrontEndOptions');
 
     final String depfilePath = fs.path.join(outputPath, 'kernel_compile.d');
+    final KernelCompiler kernelCompiler = await kernelCompilerFactory.create();
     final CompilerOutput compilerOutput = await kernelCompiler.compile(
       sdkRoot: artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath),
       mainPath: mainPath,
diff --git a/packages/flutter_tools/lib/src/bundle.dart b/packages/flutter_tools/lib/src/bundle.dart
index e90ce9b..4b9baed 100644
--- a/packages/flutter_tools/lib/src/bundle.dart
+++ b/packages/flutter_tools/lib/src/bundle.dart
@@ -99,6 +99,7 @@
     if ((extraFrontEndOptions != null) && extraFrontEndOptions.isNotEmpty)
       printTrace('Extra front-end options: $extraFrontEndOptions');
     ensureDirectoryExists(applicationKernelFilePath);
+    final KernelCompiler kernelCompiler = await kernelCompilerFactory.create();
     final CompilerOutput compilerOutput = await kernelCompiler.compile(
       sdkRoot: artifacts.getArtifactPath(Artifact.flutterPatchedSdkPath),
       incrementalCompilerByteStorePath: compilationTraceFilePath != null ? null :
diff --git a/packages/flutter_tools/lib/src/compile.dart b/packages/flutter_tools/lib/src/compile.dart
index 5b87385..158c33a 100644
--- a/packages/flutter_tools/lib/src/compile.dart
+++ b/packages/flutter_tools/lib/src/compile.dart
@@ -20,10 +20,21 @@
 import 'dart/package_map.dart';
 import 'globals.dart';
 
-KernelCompiler get kernelCompiler => context[KernelCompiler];
+KernelCompilerFactory get kernelCompilerFactory => context[KernelCompilerFactory];
 
 typedef CompilerMessageConsumer = void Function(String message, {bool emphasis, TerminalColor color});
 
+/// Injectable factory to allow async construction of a [KernelCompiler].
+class KernelCompilerFactory {
+  const KernelCompilerFactory();
+
+  /// Return the correct [KernelCompiler] instance for the given project
+  /// configuration.
+  FutureOr<KernelCompiler> create() async {
+    return const KernelCompiler();
+  }
+}
+
 /// The target model describes the set of core libraries that are availible within
 /// the SDK.
 class TargetModel {
diff --git a/packages/flutter_tools/lib/src/context_runner.dart b/packages/flutter_tools/lib/src/context_runner.dart
index 54ff657..deb0e22 100644
--- a/packages/flutter_tools/lib/src/context_runner.dart
+++ b/packages/flutter_tools/lib/src/context_runner.dart
@@ -81,7 +81,7 @@
       IOSSimulatorUtils: () => IOSSimulatorUtils(),
       IOSWorkflow: () => const IOSWorkflow(),
       IOSValidator: () => const IOSValidator(),
-      KernelCompiler: () => const KernelCompiler(),
+      KernelCompilerFactory: () => const KernelCompilerFactory(),
       LinuxWorkflow: () => const LinuxWorkflow(),
       Logger: () => platform.isWindows ? WindowsStdoutLogger() : StdoutLogger(),
       MacOSWorkflow: () => const MacOSWorkflow(),
diff --git a/packages/flutter_tools/test/compile_test.dart b/packages/flutter_tools/test/compile_test.dart
index e54595b..f808842 100644
--- a/packages/flutter_tools/test/compile_test.dart
+++ b/packages/flutter_tools/test/compile_test.dart
@@ -117,6 +117,7 @@
               'result abc\nline1\nline2\nabc /path/to/main.dart.dill 0'
             ))
           ));
+      final KernelCompiler kernelCompiler = await kernelCompilerFactory.create();
       final CompilerOutput output = await kernelCompiler.compile(sdkRoot: '/path/to/sdkroot',
         mainPath: '/path/to/main.dart',
         trackWidgetCreation: false,
@@ -140,7 +141,7 @@
               'result abc\nline1\nline2\nabc'
             ))
           ));
-
+      final KernelCompiler kernelCompiler = await kernelCompilerFactory.create();
       final CompilerOutput output = await kernelCompiler.compile(sdkRoot: '/path/to/sdkroot',
         mainPath: '/path/to/main.dart',
         trackWidgetCreation: false,
@@ -166,7 +167,7 @@
               'result abc\nline1\nline2\nabc'
           ))
       ));
-
+      final KernelCompiler kernelCompiler = await kernelCompilerFactory.create();
       final CompilerOutput output = await kernelCompiler.compile(
         sdkRoot: '/path/to/sdkroot',
         mainPath: '/path/to/main.dart',
diff --git a/packages/flutter_tools/test/tester/flutter_tester_test.dart b/packages/flutter_tools/test/tester/flutter_tester_test.dart
index 5b7aa26..3d9961e 100644
--- a/packages/flutter_tools/test/tester/flutter_tester_test.dart
+++ b/packages/flutter_tools/test/tester/flutter_tester_test.dart
@@ -102,6 +102,7 @@
       MockArtifacts mockArtifacts;
       MockKernelCompiler mockKernelCompiler;
       MockProcessManager mockProcessManager;
+      MockKernelCompilerFactory mockKernelCompilerFactory;
       MockProcess mockProcess;
 
       final Map<Type, Generator> startOverrides = <Type, Generator>{
@@ -109,7 +110,7 @@
         FileSystem: () => fs,
         Cache: () => Cache(rootOverride: fs.directory(flutterRoot)),
         ProcessManager: () => mockProcessManager,
-        KernelCompiler: () => mockKernelCompiler,
+        KernelCompilerFactory: () => mockKernelCompilerFactory,
         Artifacts: () => mockArtifacts,
       };
 
@@ -135,6 +136,10 @@
         when(mockArtifacts.getArtifactPath(any)).thenReturn(artifactPath);
 
         mockKernelCompiler = MockKernelCompiler();
+        mockKernelCompilerFactory = MockKernelCompilerFactory();
+        when(mockKernelCompilerFactory.create()).thenAnswer((Invocation invocation) async {
+          return mockKernelCompiler;
+        });
       });
 
       testUsingContext('not debug', () async {
@@ -194,3 +199,4 @@
 
 class MockArtifacts extends Mock implements Artifacts {}
 class MockKernelCompiler extends Mock implements KernelCompiler {}
+class MockKernelCompilerFactory extends Mock implements KernelCompilerFactory {}