From 2e32ffc004be74a0a13057349641141239a610ea Mon Sep 17 00:00:00 2001 From: Pranav K Date: Wed, 9 Sep 2015 18:25:11 -0700 Subject: [PATCH] Use PrecompilationTagHelperTypeResolver to locate TagHelpers during precompilation. Fixes #2298 --- ...ecompilationTagHelperDescriptorResolver.cs | 88 ------------------- .../Precompilation/RazorPreCompileModule.cs | 13 --- .../Precompilation/RazorPreCompiler.cs | 16 ++-- src/Microsoft.AspNet.Mvc.Razor/project.json | 1 + .../preprocess/RazorPreCompilation.cs | 3 +- 5 files changed, 9 insertions(+), 112 deletions(-) delete mode 100644 src/Microsoft.AspNet.Mvc.Razor/Precompilation/PrecompilationTagHelperDescriptorResolver.cs diff --git a/src/Microsoft.AspNet.Mvc.Razor/Precompilation/PrecompilationTagHelperDescriptorResolver.cs b/src/Microsoft.AspNet.Mvc.Razor/Precompilation/PrecompilationTagHelperDescriptorResolver.cs deleted file mode 100644 index d794225af7..0000000000 --- a/src/Microsoft.AspNet.Mvc.Razor/Precompilation/PrecompilationTagHelperDescriptorResolver.cs +++ /dev/null @@ -1,88 +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; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Threading; -using Microsoft.AspNet.Razor.Runtime.TagHelpers; -using Microsoft.Dnx.Compilation.CSharp; -using Microsoft.Dnx.Runtime; -using Microsoft.Framework.Internal; - -namespace Microsoft.AspNet.Mvc.Razor.Precompilation -{ - /// - /// used during Razor precompilation. - /// - public class PrecompilationTagHelperTypeResolver : TagHelperTypeResolver - { - private static readonly string TagHelperTypeName = typeof(ITagHelper).FullName; - private readonly BeforeCompileContext _compileContext; - private readonly IAssemblyLoadContext _loadContext; - private object _compilationLock = new object(); - private bool _assemblyEmited; - private TypeInfo[] _exportedTypeInfos; - - /// - /// Initializes a new instance of . - /// - /// The . - /// The . - public PrecompilationTagHelperTypeResolver([NotNull] BeforeCompileContext compileContext, - [NotNull] IAssemblyLoadContext loadContext) - { - _compileContext = compileContext; - _loadContext = loadContext; - } - - /// - protected override IEnumerable GetExportedTypes([NotNull] AssemblyName assemblyName) - { - var compilingAssemblyName = _compileContext.Compilation.AssemblyName; - if (string.Equals(assemblyName.Name, compilingAssemblyName, StringComparison.Ordinal)) - { - return LazyInitializer.EnsureInitialized(ref _exportedTypeInfos, - ref _assemblyEmited, - ref _compilationLock, - GetExportedTypesFromCompilation); - } - - return GetExportedTypesCore(assemblyName); - } - - private IEnumerable GetExportedTypesCore(AssemblyName assemblyName) - { - var assembly = _loadContext.Load(assemblyName.Name); - - return assembly.ExportedTypes.Select(type => type.GetTypeInfo()); - } - - private TypeInfo[] GetExportedTypesFromCompilation() - { - using (var stream = new MemoryStream()) - { - var assemblyName = string.Join(".", _compileContext.Compilation.AssemblyName, - nameof(PrecompilationTagHelperTypeResolver), - Path.GetRandomFileName()); - - var emitResult = _compileContext.Compilation - .WithAssemblyName(assemblyName) - .Emit(stream); - if (!emitResult.Success) - { - // Return an empty sequence. Compilation will fail once precompilation completes. - return new TypeInfo[0]; - } - - stream.Position = 0; - var assembly = _loadContext.LoadStream(stream, assemblySymbols: null); - return assembly.ExportedTypes - .Select(type => type.GetTypeInfo()) - .ToArray(); - } - } - } -} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Razor/Precompilation/RazorPreCompileModule.cs b/src/Microsoft.AspNet.Mvc.Razor/Precompilation/RazorPreCompileModule.cs index fb1d7b6ba6..6a4cdad8f7 100644 --- a/src/Microsoft.AspNet.Mvc.Razor/Precompilation/RazorPreCompileModule.cs +++ b/src/Microsoft.AspNet.Mvc.Razor/Precompilation/RazorPreCompileModule.cs @@ -6,9 +6,7 @@ using System.Runtime.Versioning; using Microsoft.AspNet.FileProviders; using Microsoft.Dnx.Compilation.CSharp; -using Microsoft.Dnx.Runtime; using Microsoft.Framework.Caching.Memory; -using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.Internal; namespace Microsoft.AspNet.Mvc.Razor.Precompilation @@ -18,20 +16,10 @@ namespace Microsoft.AspNet.Mvc.Razor.Precompilation /// public abstract class RazorPreCompileModule : ICompileModule { - private readonly IAssemblyLoadContext _loadContext; private readonly object _memoryCacheLookupLock = new object(); private readonly Dictionary _memoryCacheLookup = new Dictionary(); - /// - /// Instantiates a new instance. - /// - /// The for the application. - public RazorPreCompileModule(IServiceProvider services) - { - _loadContext = services.GetRequiredService(); - } - /// /// Gets or sets a value that determines if symbols (.pdb) file for the precompiled views is generated. /// @@ -65,7 +53,6 @@ public virtual void BeforeCompile(BeforeCompileContext context) var viewCompiler = new RazorPreCompiler( context, - _loadContext, fileProvider, memoryCache) { diff --git a/src/Microsoft.AspNet.Mvc.Razor/Precompilation/RazorPreCompiler.cs b/src/Microsoft.AspNet.Mvc.Razor/Precompilation/RazorPreCompiler.cs index 8cd91bea65..727c2153a9 100644 --- a/src/Microsoft.AspNet.Mvc.Razor/Precompilation/RazorPreCompiler.cs +++ b/src/Microsoft.AspNet.Mvc.Razor/Precompilation/RazorPreCompiler.cs @@ -3,21 +3,21 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; -using System.Reflection; using System.Threading.Tasks; using Microsoft.AspNet.FileProviders; using Microsoft.AspNet.Mvc.Internal; using Microsoft.AspNet.Mvc.Razor.Compilation; using Microsoft.AspNet.Mvc.Razor.Directives; using Microsoft.AspNet.Mvc.Razor.Internal; +using Microsoft.AspNet.Razor.Runtime.Precompilation; using Microsoft.AspNet.Razor.Runtime.TagHelpers; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.Dnx.Compilation; using Microsoft.Dnx.Compilation.CSharp; -using Microsoft.Dnx.Runtime; using Microsoft.Framework.Caching.Memory; using Microsoft.Framework.Internal; @@ -27,22 +27,22 @@ public class RazorPreCompiler { public RazorPreCompiler( [NotNull] BeforeCompileContext compileContext, - [NotNull] IAssemblyLoadContext loadContext, [NotNull] IFileProvider fileProvider, [NotNull] IMemoryCache precompilationCache) { CompileContext = compileContext; - LoadContext = loadContext; FileProvider = fileProvider; + // There should always be a syntax tree even if there are no files (we generate one) + Debug.Assert(compileContext.Compilation.SyntaxTrees.Length > 0); + var defines = compileContext.Compilation.SyntaxTrees[0].Options.PreprocessorSymbolNames; CompilationSettings = new CompilationSettings { CompilationOptions = compileContext.Compilation.Options, - // REVIEW: There should always be a syntax tree even if there are no files (we generate one) - Defines = compileContext.Compilation.SyntaxTrees[0].Options.PreprocessorSymbolNames, + Defines = defines, LanguageVersion = compileContext.Compilation.LanguageVersion }; PreCompilationCache = precompilationCache; - TagHelperTypeResolver = new PrecompilationTagHelperTypeResolver(CompileContext, LoadContext); + TagHelperTypeResolver = new PrecompilationTagHelperTypeResolver(CompileContext.Compilation); } /// @@ -54,8 +54,6 @@ public RazorPreCompiler( protected BeforeCompileContext CompileContext { get; } - protected IAssemblyLoadContext LoadContext { get; } - protected CompilationSettings CompilationSettings { get; } protected IMemoryCache PreCompilationCache { get; } diff --git a/src/Microsoft.AspNet.Mvc.Razor/project.json b/src/Microsoft.AspNet.Mvc.Razor/project.json index 5337b3cade..48f1cbfd04 100644 --- a/src/Microsoft.AspNet.Mvc.Razor/project.json +++ b/src/Microsoft.AspNet.Mvc.Razor/project.json @@ -11,6 +11,7 @@ "dependencies": { "Microsoft.AspNet.Mvc.Razor.Host": "6.0.0-*", "Microsoft.AspNet.Mvc.ViewFeatures": "6.0.0-*", + "Microsoft.AspNet.Razor.Runtime.Precompilation": "4.0.0-*", "Microsoft.AspNet.PageExecutionInstrumentation.Interfaces": "1.0.0-*", "Microsoft.Framework.HashCodeCombiner.Sources": { "version": "1.0.0-*", "type": "build" }, "Microsoft.Framework.NotNullAttribute.Sources": { "version": "1.0.0-*", "type": "build" }, diff --git a/test/WebSites/PrecompilationWebSite/compiler/preprocess/RazorPreCompilation.cs b/test/WebSites/PrecompilationWebSite/compiler/preprocess/RazorPreCompilation.cs index 0edf7e412f..727e6766fd 100644 --- a/test/WebSites/PrecompilationWebSite/compiler/preprocess/RazorPreCompilation.cs +++ b/test/WebSites/PrecompilationWebSite/compiler/preprocess/RazorPreCompilation.cs @@ -8,8 +8,7 @@ namespace PrecompilationWebSite { public class RazorPreCompilation : RazorPreCompileModule { - public RazorPreCompilation(IServiceProvider provider) - : base(provider) + public RazorPreCompilation() { } }