diff --git a/src/Microsoft.AspNet.Mvc.Razor/Internal/RazorFileInfoCollectionGenerator.cs b/src/Microsoft.AspNet.Mvc.Razor/Internal/RazorFileInfoCollectionGenerator.cs
new file mode 100644
index 0000000000..954a27ee20
--- /dev/null
+++ b/src/Microsoft.AspNet.Mvc.Razor/Internal/RazorFileInfoCollectionGenerator.cs
@@ -0,0 +1,71 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Runtime.CompilerServices;
+using System.Text;
+using Microsoft.AspNet.Mvc.Razor.Precompilation;
+using Microsoft.Dnx.Runtime;
+using Microsoft.Framework.Internal;
+
+namespace Microsoft.AspNet.Mvc.Razor.Internal
+{
+ ///
+ /// Utility type to code generate types.
+ ///
+ public static class RazorFileInfoCollectionGenerator
+ {
+ ///
+ /// Generates CSharp code for the specified .
+ ///
+ /// The .
+ ///
+ public static string GenerateCode([NotNull] RazorFileInfoCollection fileInfoCollection)
+ {
+ var builder = new StringBuilder();
+
+ builder.Append(
+$@"namespace __ASP_ASSEMBLY
+{{
+ [{typeof(CompilerGeneratedAttribute).FullName}]
+ public class __PreGeneratedViewCollection : {typeof(RazorFileInfoCollection).FullName}
+ {{
+ public __PreGeneratedViewCollection()
+ {{
+ {nameof(RazorFileInfoCollection.AssemblyResourceName)} = @""{fileInfoCollection.AssemblyResourceName}"";
+ {nameof(RazorFileInfoCollection.SymbolsResourceName)} = @""{fileInfoCollection.SymbolsResourceName}"";
+ FileInfos = new System.Collections.Generic.List<{typeof(RazorFileInfo).FullName}>
+ {{");
+
+ foreach (var fileInfo in fileInfoCollection.FileInfos)
+ {
+ builder.Append(
+$@"
+ new {typeof(RazorFileInfo).FullName}
+ {{
+ {nameof(RazorFileInfo.FullTypeName)} = @""{fileInfo.FullTypeName}"",
+ {nameof(RazorFileInfo.RelativePath)} = @""{fileInfo.RelativePath}""
+ }},");
+ }
+
+ builder.Append(
+$@"
+ }};
+ }}
+
+ private static {typeof(System.Reflection.Assembly).FullName} _loadedAssembly;
+
+ public override {typeof(System.Reflection.Assembly).FullName} LoadAssembly(
+ {typeof(IAssemblyLoadContext).FullName} loadContext)
+ {{
+ if (_loadedAssembly == null)
+ {{
+ _loadedAssembly = base.LoadAssembly(loadContext);
+ }}
+ return _loadedAssembly;
+ }}
+ }}
+}}");
+ return builder.ToString();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.Razor/Precompilation/RazorFileInfoCollectionGenerator.cs b/src/Microsoft.AspNet.Mvc.Razor/Precompilation/RazorFileInfoCollectionGenerator.cs
deleted file mode 100644
index 8a590ba907..0000000000
--- a/src/Microsoft.AspNet.Mvc.Razor/Precompilation/RazorFileInfoCollectionGenerator.cs
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-
-using System.Globalization;
-using System.Text;
-using Microsoft.AspNet.Mvc.Razor.Compilation;
-using Microsoft.CodeAnalysis;
-using Microsoft.Dnx.Compilation.CSharp;
-using Microsoft.Dnx.Runtime;
-using Microsoft.Framework.Internal;
-
-namespace Microsoft.AspNet.Mvc.Razor.Precompilation
-{
- public class RazorFileInfoCollectionGenerator
- {
- private string _fileFormat;
-
- public RazorFileInfoCollectionGenerator([NotNull] RazorFileInfoCollection fileInfoCollection,
- [NotNull] CompilationSettings compilationSettings)
- {
- RazorFileInfoCollection = fileInfoCollection;
- CompilationSettings = compilationSettings;
- }
-
- protected RazorFileInfoCollection RazorFileInfoCollection { get; }
-
- protected CompilationSettings CompilationSettings { get; }
-
- public virtual SyntaxTree GenerateCollection()
- {
- var builder = new StringBuilder();
- builder.AppendFormat(CultureInfo.InvariantCulture,
- TopFormat,
- RazorFileInfoCollection.AssemblyResourceName,
- RazorFileInfoCollection.SymbolsResourceName);
-
- foreach (var fileInfo in RazorFileInfoCollection.FileInfos)
- {
- var perFileEntry = GenerateFile(fileInfo);
- builder.Append(perFileEntry);
- }
-
- builder.Append(Bottom);
-
- var sourceCode = builder.ToString();
- var syntaxTree = SyntaxTreeGenerator.Generate(sourceCode,
- "__AUTO__GeneratedViewsCollection.cs",
- CompilationSettings);
-
- return syntaxTree;
- }
-
- protected virtual string GenerateFile([NotNull] RazorFileInfo fileInfo)
- {
- return string.Format(FileFormat,
- fileInfo.RelativePath,
- fileInfo.FullTypeName);
- }
-
- protected virtual string TopFormat
- {
- get
- {
- return
-$@"using System;
-using System.Collections.Generic;
-using System.Reflection;
-using {typeof(RazorFileInfoCollection).Namespace};
-
-namespace __ASP_ASSEMBLY
-{{{{
- public class __PreGeneratedViewCollection : {nameof(RazorFileInfoCollection)}
- {{{{
- public __PreGeneratedViewCollection()
- {{{{
- {nameof(RazorFileInfoCollection.AssemblyResourceName)} = ""{{0}}"";
- {nameof(RazorFileInfoCollection.SymbolsResourceName)} = ""{{1}}"";
- var fileInfos = new List<{nameof(RazorFileInfo)}>();
- {nameof(RazorFileInfoCollection.FileInfos)} = fileInfos;
- {nameof(RazorFileInfo)} info;
-";
- }
- }
-
- protected virtual string Bottom
- {
- get
- {
- return
- $@"
- }}
- private static Assembly _loadedAssembly;
-
- public override Assembly LoadAssembly({typeof(IAssemblyLoadContext).FullName} loadContext)
- {{
- if (_loadedAssembly == null)
- {{
- _loadedAssembly = base.LoadAssembly(loadContext);
- }}
- return _loadedAssembly;
- }}
- }}
-}}
-";
- }
- }
-
- protected virtual string FileFormat
- {
- get
- {
- if (_fileFormat == null)
- {
- _fileFormat =
- $@"
- info = new {nameof(RazorFileInfo)}
- {{{{
- {nameof(RazorFileInfo.RelativePath)} = @""{{0}}"",
- {nameof(RazorFileInfo.FullTypeName)} = @""{{1}}""
- }}}};
- fileInfos.Add(info);
-";
- }
-
- return _fileFormat;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.Razor/Precompilation/RazorPreCompiler.cs b/src/Microsoft.AspNet.Mvc.Razor/Precompilation/RazorPreCompiler.cs
index 3749b43448..10bd897a8c 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/Precompilation/RazorPreCompiler.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor/Precompilation/RazorPreCompiler.cs
@@ -64,12 +64,11 @@ namespace Microsoft.AspNet.Mvc.Razor.Precompilation
var result = CreateFileInfoCollection();
if (result != null)
{
- var collectionGenerator = new RazorFileInfoCollectionGenerator(
- result,
- CompilationSettings);
-
- var tree = collectionGenerator.GenerateCollection();
- CompileContext.Compilation = CompileContext.Compilation.AddSyntaxTrees(tree);
+ var generatedCode = RazorFileInfoCollectionGenerator.GenerateCode(result);
+ var syntaxTree = CSharpSyntaxTree.ParseText(
+ generatedCode,
+ SyntaxTreeGenerator.GetParseOptions(CompilationSettings));
+ CompileContext.Compilation = CompileContext.Compilation.AddSyntaxTrees(syntaxTree);
}
}
diff --git a/test/Microsoft.AspNet.Mvc.Razor.Test/Internal/RazorFileInfoCollectionGeneratorTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Test/Internal/RazorFileInfoCollectionGeneratorTest.cs
new file mode 100644
index 0000000000..1730d74efb
--- /dev/null
+++ b/test/Microsoft.AspNet.Mvc.Razor.Test/Internal/RazorFileInfoCollectionGeneratorTest.cs
@@ -0,0 +1,135 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using Microsoft.AspNet.Mvc.Razor.Compilation;
+using Microsoft.AspNet.Mvc.Razor.Precompilation;
+using Microsoft.CodeAnalysis.CSharp;
+using Xunit;
+
+namespace Microsoft.AspNet.Mvc.Razor.Internal
+{
+ public class RazorFileInfoCollectionGeneratorTest
+ {
+ public static TheoryData GenerateCollection_ProducesExpectedCodeData
+ {
+ get
+ {
+ var expected1 =
+@"namespace __ASP_ASSEMBLY
+{
+ [System.Runtime.CompilerServices.CompilerGeneratedAttribute]
+ public class __PreGeneratedViewCollection : Microsoft.AspNet.Mvc.Razor.Precompilation.RazorFileInfoCollection
+ {
+ public __PreGeneratedViewCollection()
+ {
+ AssemblyResourceName = @""EmptyAssembly"";
+ SymbolsResourceName = @"""";
+ FileInfos = new System.Collections.Generic.List
+ {
+ };
+ }
+
+ private static System.Reflection.Assembly _loadedAssembly;
+
+ public override System.Reflection.Assembly LoadAssembly(
+ Microsoft.Dnx.Runtime.IAssemblyLoadContext loadContext)
+ {
+ if (_loadedAssembly == null)
+ {
+ _loadedAssembly = base.LoadAssembly(loadContext);
+ }
+ return _loadedAssembly;
+ }
+ }
+}";
+ var expected2 =
+@"namespace __ASP_ASSEMBLY
+{
+ [System.Runtime.CompilerServices.CompilerGeneratedAttribute]
+ public class __PreGeneratedViewCollection : Microsoft.AspNet.Mvc.Razor.Precompilation.RazorFileInfoCollection
+ {
+ public __PreGeneratedViewCollection()
+ {
+ AssemblyResourceName = @""TestAssembly"";
+ SymbolsResourceName = @""SymbolsResource"";
+ FileInfos = new System.Collections.Generic.List
+ {
+ new Microsoft.AspNet.Mvc.Razor.Precompilation.RazorFileInfo
+ {
+ FullTypeName = @""SomeType.Name"",
+ RelativePath = @""Views/Home/Index.cshtml""
+ },
+ new Microsoft.AspNet.Mvc.Razor.Precompilation.RazorFileInfo
+ {
+ FullTypeName = @""Different.Name"",
+ RelativePath = @""Views/Home/Different.cshtml""
+ },
+ };
+ }
+
+ private static System.Reflection.Assembly _loadedAssembly;
+
+ public override System.Reflection.Assembly LoadAssembly(
+ Microsoft.Dnx.Runtime.IAssemblyLoadContext loadContext)
+ {
+ if (_loadedAssembly == null)
+ {
+ _loadedAssembly = base.LoadAssembly(loadContext);
+ }
+ return _loadedAssembly;
+ }
+ }
+}";
+
+ return new TheoryData
+ {
+ { new EmptyCollection(), expected1 },
+ { new TestCollection(), expected2 },
+ };
+ }
+ }
+
+ [Theory]
+ [MemberData(nameof(GenerateCollection_ProducesExpectedCodeData))]
+ public void GenerateCollection_ProducesExpectedCode(RazorFileInfoCollection collection, string expected)
+ {
+ // Act
+ var actual = RazorFileInfoCollectionGenerator.GenerateCode(collection);
+
+ // Assert
+ Assert.Equal(expected, actual);
+ }
+
+ private class EmptyCollection : RazorFileInfoCollection
+ {
+ public EmptyCollection()
+ {
+ AssemblyResourceName = "EmptyAssembly";
+ FileInfos = new List();
+ }
+ }
+
+ private class TestCollection : RazorFileInfoCollection
+ {
+ public TestCollection()
+ {
+ AssemblyResourceName = "TestAssembly";
+ SymbolsResourceName = "SymbolsResource";
+ FileInfos = new List
+ {
+ new RazorFileInfo
+ {
+ FullTypeName = "SomeType.Name",
+ RelativePath = @"Views/Home/Index.cshtml"
+ },
+ new RazorFileInfo
+ {
+ FullTypeName = "Different.Name",
+ RelativePath = @"Views/Home/Different.cshtml"
+ },
+ };
+ }
+ }
+ }
+}