Use PrecompilationTagHelperTypeResolver to locate TagHelpers during
precompilation. Fixes #2298
This commit is contained in:
parent
894574d04e
commit
2e32ffc004
|
|
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="TagHelperDescriptorResolver"/> used during Razor precompilation.
|
||||
/// </summary>
|
||||
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;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="PrecompilationTagHelperTypeResolver"/>.
|
||||
/// </summary>
|
||||
/// <param name="compileContext">The <see cref="BeforeCompileContext"/>.</param>
|
||||
/// <param name="loadContext">The <see cref="IAssemblyLoadContext"/>.</param>
|
||||
public PrecompilationTagHelperTypeResolver([NotNull] BeforeCompileContext compileContext,
|
||||
[NotNull] IAssemblyLoadContext loadContext)
|
||||
{
|
||||
_compileContext = compileContext;
|
||||
_loadContext = loadContext;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IEnumerable<TypeInfo> 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<TypeInfo> 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,9 +6,7 @@ using System.Collections.Generic;
|
|||
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
|
|||
/// </summary>
|
||||
public abstract class RazorPreCompileModule : ICompileModule
|
||||
{
|
||||
private readonly IAssemblyLoadContext _loadContext;
|
||||
private readonly object _memoryCacheLookupLock = new object();
|
||||
private readonly Dictionary<PrecompilationCacheKey, MemoryCache> _memoryCacheLookup =
|
||||
new Dictionary<PrecompilationCacheKey, MemoryCache>();
|
||||
|
||||
/// <summary>
|
||||
/// Instantiates a new <see cref="RazorPreCompileModule"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="services">The <see cref="IServiceProvider"/> for the application.</param>
|
||||
public RazorPreCompileModule(IServiceProvider services)
|
||||
{
|
||||
_loadContext = services.GetRequiredService<IAssemblyLoadContext>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value that determines if symbols (.pdb) file for the precompiled views is generated.
|
||||
/// </summary>
|
||||
|
|
@ -65,7 +53,6 @@ namespace Microsoft.AspNet.Mvc.Razor.Precompilation
|
|||
|
||||
var viewCompiler = new RazorPreCompiler(
|
||||
context,
|
||||
_loadContext,
|
||||
fileProvider,
|
||||
memoryCache)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 @@ namespace Microsoft.AspNet.Mvc.Razor.Precompilation
|
|||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -54,8 +54,6 @@ namespace Microsoft.AspNet.Mvc.Razor.Precompilation
|
|||
|
||||
protected BeforeCompileContext CompileContext { get; }
|
||||
|
||||
protected IAssemblyLoadContext LoadContext { get; }
|
||||
|
||||
protected CompilationSettings CompilationSettings { get; }
|
||||
|
||||
protected IMemoryCache PreCompilationCache { get; }
|
||||
|
|
|
|||
|
|
@ -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" },
|
||||
|
|
|
|||
|
|
@ -8,8 +8,7 @@ namespace PrecompilationWebSite
|
|||
{
|
||||
public class RazorPreCompilation : RazorPreCompileModule
|
||||
{
|
||||
public RazorPreCompilation(IServiceProvider provider)
|
||||
: base(provider)
|
||||
public RazorPreCompilation()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue