зеркало из https://github.com/aspnet/Mvc.git
Remove Razor precompilation
This commit is contained in:
Родитель
d0046cafe9
Коммит
32d15186a0
|
@ -99,7 +99,7 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "LocalizationSample.Web", "s
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ActionConstraintSample.Web", "samples\ActionConstraintSample.Web\ActionConstraintSample.Web.xproj", "{EE0BD773-4D47-4AA8-8472-5A938A3953BA}"
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ActionConstraintSample.Web", "samples\ActionConstraintSample.Web\ActionConstraintSample.Web.xproj", "{EE0BD773-4D47-4AA8-8472-5A938A3953BA}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "MvcSubAreaSample.Web", "samples\MvcSubAreaSample.Web\MvcSubAreaSample.Web.xproj", "{E1D45BAF-3967-4D81-9217-22AA54941BF5}"
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "MvcSubAreaSample.Web", "samples\MvcSubAreaSample.Web\MvcSubAreaSample.Web.xproj", "{45F6B3B6-D114-4D77-84D6-561B3957F341}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
@ -593,18 +593,18 @@ Global
|
||||||
{EE0BD773-4D47-4AA8-8472-5A938A3953BA}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
{EE0BD773-4D47-4AA8-8472-5A938A3953BA}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||||
{EE0BD773-4D47-4AA8-8472-5A938A3953BA}.Release|x86.ActiveCfg = Release|Any CPU
|
{EE0BD773-4D47-4AA8-8472-5A938A3953BA}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{EE0BD773-4D47-4AA8-8472-5A938A3953BA}.Release|x86.Build.0 = Release|Any CPU
|
{EE0BD773-4D47-4AA8-8472-5A938A3953BA}.Release|x86.Build.0 = Release|Any CPU
|
||||||
{E1D45BAF-3967-4D81-9217-22AA54941BF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{45F6B3B6-D114-4D77-84D6-561B3957F341}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{E1D45BAF-3967-4D81-9217-22AA54941BF5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{45F6B3B6-D114-4D77-84D6-561B3957F341}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{E1D45BAF-3967-4D81-9217-22AA54941BF5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
{45F6B3B6-D114-4D77-84D6-561B3957F341}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||||
{E1D45BAF-3967-4D81-9217-22AA54941BF5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
{45F6B3B6-D114-4D77-84D6-561B3957F341}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||||
{E1D45BAF-3967-4D81-9217-22AA54941BF5}.Debug|x86.ActiveCfg = Debug|Any CPU
|
{45F6B3B6-D114-4D77-84D6-561B3957F341}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
{E1D45BAF-3967-4D81-9217-22AA54941BF5}.Debug|x86.Build.0 = Debug|Any CPU
|
{45F6B3B6-D114-4D77-84D6-561B3957F341}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
{E1D45BAF-3967-4D81-9217-22AA54941BF5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{45F6B3B6-D114-4D77-84D6-561B3957F341}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{E1D45BAF-3967-4D81-9217-22AA54941BF5}.Release|Any CPU.Build.0 = Release|Any CPU
|
{45F6B3B6-D114-4D77-84D6-561B3957F341}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{E1D45BAF-3967-4D81-9217-22AA54941BF5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
{45F6B3B6-D114-4D77-84D6-561B3957F341}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||||
{E1D45BAF-3967-4D81-9217-22AA54941BF5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
{45F6B3B6-D114-4D77-84D6-561B3957F341}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||||
{E1D45BAF-3967-4D81-9217-22AA54941BF5}.Release|x86.ActiveCfg = Release|Any CPU
|
{45F6B3B6-D114-4D77-84D6-561B3957F341}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{E1D45BAF-3967-4D81-9217-22AA54941BF5}.Release|x86.Build.0 = Release|Any CPU
|
{45F6B3B6-D114-4D77-84D6-561B3957F341}.Release|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -652,6 +652,6 @@ Global
|
||||||
{DAB1252D-577C-4912-98BE-1A812BF83F86} = {DAAE4C74-D06F-4874-A166-33305D2643CE}
|
{DAB1252D-577C-4912-98BE-1A812BF83F86} = {DAAE4C74-D06F-4874-A166-33305D2643CE}
|
||||||
{FCFE6024-2720-49B4-8257-9DBC6114F0F1} = {DAAE4C74-D06F-4874-A166-33305D2643CE}
|
{FCFE6024-2720-49B4-8257-9DBC6114F0F1} = {DAAE4C74-D06F-4874-A166-33305D2643CE}
|
||||||
{EE0BD773-4D47-4AA8-8472-5A938A3953BA} = {DAAE4C74-D06F-4874-A166-33305D2643CE}
|
{EE0BD773-4D47-4AA8-8472-5A938A3953BA} = {DAAE4C74-D06F-4874-A166-33305D2643CE}
|
||||||
{E1D45BAF-3967-4D81-9217-22AA54941BF5} = {DAAE4C74-D06F-4874-A166-33305D2643CE}
|
{45F6B3B6-D114-4D77-84D6-561B3957F341} = {DAAE4C74-D06F-4874-A166-33305D2643CE}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
13
Mvc.sln
13
Mvc.sln
|
@ -70,8 +70,6 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.TagHel
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.TagHelpers.Test", "test\Microsoft.AspNet.Mvc.TagHelpers.Test\Microsoft.AspNet.Mvc.TagHelpers.Test.xproj", "{860119ED-3DB1-424D-8D0A-30132A8A7D96}"
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.TagHelpers.Test", "test\Microsoft.AspNet.Mvc.TagHelpers.Test\Microsoft.AspNet.Mvc.TagHelpers.Test.xproj", "{860119ED-3DB1-424D-8D0A-30132A8A7D96}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "PrecompilationWebSite", "test\WebSites\PrecompilationWebSite\PrecompilationWebSite.xproj", "{59E1BE90-92C1-4D35-ADCC-B69F49077C81}"
|
|
||||||
EndProject
|
|
||||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "HtmlGenerationWebSite", "test\WebSites\HtmlGenerationWebSite\HtmlGenerationWebSite.xproj", "{920F8A0E-6F7D-4BBE-84FF-840B89099BE6}"
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "HtmlGenerationWebSite", "test\WebSites\HtmlGenerationWebSite\HtmlGenerationWebSite.xproj", "{920F8A0E-6F7D-4BBE-84FF-840B89099BE6}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ErrorPageMiddlewareWebSite", "test\WebSites\ErrorPageMiddlewareWebSite\ErrorPageMiddlewareWebSite.xproj", "{AD545A5B-2BA5-4314-88AC-FC2ACF2CC718}"
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ErrorPageMiddlewareWebSite", "test\WebSites\ErrorPageMiddlewareWebSite\ErrorPageMiddlewareWebSite.xproj", "{AD545A5B-2BA5-4314-88AC-FC2ACF2CC718}"
|
||||||
|
@ -426,16 +424,6 @@ Global
|
||||||
{860119ED-3DB1-424D-8D0A-30132A8A7D96}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
{860119ED-3DB1-424D-8D0A-30132A8A7D96}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||||
{860119ED-3DB1-424D-8D0A-30132A8A7D96}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
{860119ED-3DB1-424D-8D0A-30132A8A7D96}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||||
{860119ED-3DB1-424D-8D0A-30132A8A7D96}.Release|x86.ActiveCfg = Release|Any CPU
|
{860119ED-3DB1-424D-8D0A-30132A8A7D96}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{59E1BE90-92C1-4D35-ADCC-B69F49077C81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{59E1BE90-92C1-4D35-ADCC-B69F49077C81}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{59E1BE90-92C1-4D35-ADCC-B69F49077C81}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
|
||||||
{59E1BE90-92C1-4D35-ADCC-B69F49077C81}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
|
||||||
{59E1BE90-92C1-4D35-ADCC-B69F49077C81}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{59E1BE90-92C1-4D35-ADCC-B69F49077C81}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{59E1BE90-92C1-4D35-ADCC-B69F49077C81}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{59E1BE90-92C1-4D35-ADCC-B69F49077C81}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
|
||||||
{59E1BE90-92C1-4D35-ADCC-B69F49077C81}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
|
||||||
{59E1BE90-92C1-4D35-ADCC-B69F49077C81}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{920F8A0E-6F7D-4BBE-84FF-840B89099BE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{920F8A0E-6F7D-4BBE-84FF-840B89099BE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{920F8A0E-6F7D-4BBE-84FF-840B89099BE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{920F8A0E-6F7D-4BBE-84FF-840B89099BE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{920F8A0E-6F7D-4BBE-84FF-840B89099BE6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
{920F8A0E-6F7D-4BBE-84FF-840B89099BE6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||||
|
@ -912,7 +900,6 @@ Global
|
||||||
{2223120F-D675-40DA-8CD8-11DC14A0B2C7} = {DAAE4C74-D06F-4874-A166-33305D2643CE}
|
{2223120F-D675-40DA-8CD8-11DC14A0B2C7} = {DAAE4C74-D06F-4874-A166-33305D2643CE}
|
||||||
{B2347320-308E-4D2B-AEC8-005DFA68B0C9} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
|
{B2347320-308E-4D2B-AEC8-005DFA68B0C9} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
|
||||||
{860119ED-3DB1-424D-8D0A-30132A8A7D96} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
|
{860119ED-3DB1-424D-8D0A-30132A8A7D96} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
|
||||||
{59E1BE90-92C1-4D35-ADCC-B69F49077C81} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
|
||||||
{920F8A0E-6F7D-4BBE-84FF-840B89099BE6} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
{920F8A0E-6F7D-4BBE-84FF-840B89099BE6} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||||
{AD545A5B-2BA5-4314-88AC-FC2ACF2CC718} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
{AD545A5B-2BA5-4314-88AC-FC2ACF2CC718} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||||
{C3123A70-41C4-4122-AD1C-D35DF8958DD7} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
{C3123A70-41C4-4122-AD1C-D35DF8958DD7} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="14.0.24720" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.24720</VisualStudioVersion>
|
||||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||||
<PropertyGroup Label="Globals">
|
<PropertyGroup Label="Globals">
|
||||||
<ProjectGuid>59e1be90-92c1-4d35-adcc-b69f49077c81</ProjectGuid>
|
<ProjectGuid>45F6B3B6-D114-4D77-84D6-561B3957F341</ProjectGuid>
|
||||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
<RootNamespace>MvcSubAreaSample.Web</RootNamespace>
|
||||||
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||||
|
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<SchemaVersion>2.0</SchemaVersion>
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
<DevelopmentServerPort>40958</DevelopmentServerPort>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
</Project>
|
</Project>
|
|
@ -1,12 +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 Microsoft.AspNet.Mvc.Razor.Precompilation;
|
|
||||||
|
|
||||||
namespace TagHelperSample.Web
|
|
||||||
{
|
|
||||||
public class TagHelpersRazorPreCompilation : RazorPreCompileModule
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,109 +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.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Threading;
|
|
||||||
using Microsoft.AspNet.FileProviders;
|
|
||||||
using Microsoft.AspNet.Mvc.Razor.Precompilation;
|
|
||||||
using Microsoft.Extensions.PlatformAbstractions;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Razor.Compilation
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// An <see cref="ICompilerCacheProvider"/> that provides a <see cref="CompilerCache"/> instance
|
|
||||||
/// populated with precompiled views.
|
|
||||||
/// </summary>
|
|
||||||
public class PrecompiledViewsCompilerCacheProvider : ICompilerCacheProvider
|
|
||||||
{
|
|
||||||
private static readonly Assembly RazorAssembly = typeof(DefaultCompilerCacheProvider).GetTypeInfo().Assembly;
|
|
||||||
private static readonly Type RazorFileInfoCollectionType = typeof(RazorFileInfoCollection);
|
|
||||||
private readonly Func<ICompilerCache> _createCache;
|
|
||||||
private readonly IAssemblyLoadContextAccessor _loadContextAccessor;
|
|
||||||
private readonly IFileProvider _fileProvider;
|
|
||||||
private readonly Assembly[] _assemblies;
|
|
||||||
|
|
||||||
private object _cacheLock = new object();
|
|
||||||
private bool _cacheInitialized;
|
|
||||||
private ICompilerCache _compilerCache;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of <see cref="DefaultCompilerCacheProvider"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="loadContextAccessor">The <see cref="IAssemblyLoadContextAccessor"/>.</param>
|
|
||||||
/// <param name="fileProviderAccessor">The <see cref="IRazorViewEngineFileProviderAccessor"/>.</param>
|
|
||||||
/// <param name="assemblies"><see cref="Assembly"/> instances to scan for precompiled views.</param>
|
|
||||||
public PrecompiledViewsCompilerCacheProvider(
|
|
||||||
IAssemblyLoadContextAccessor loadContextAccessor,
|
|
||||||
IRazorViewEngineFileProviderAccessor fileProviderAccessor,
|
|
||||||
IEnumerable<Assembly> assemblies)
|
|
||||||
{
|
|
||||||
_loadContextAccessor = loadContextAccessor;
|
|
||||||
_fileProvider = fileProviderAccessor.FileProvider;
|
|
||||||
_createCache = CreateCache;
|
|
||||||
_assemblies = assemblies.ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public ICompilerCache Cache
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return LazyInitializer.EnsureInitialized(
|
|
||||||
ref _compilerCache,
|
|
||||||
ref _cacheInitialized,
|
|
||||||
ref _cacheLock,
|
|
||||||
_createCache);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ICompilerCache CreateCache()
|
|
||||||
{
|
|
||||||
var razorFileInfoCollections = GetFileInfoCollections(_assemblies);
|
|
||||||
var loadContext = _loadContextAccessor.GetLoadContext(RazorAssembly);
|
|
||||||
var precompiledViews = GetPrecompiledViews(razorFileInfoCollections, loadContext);
|
|
||||||
|
|
||||||
return new CompilerCache(_fileProvider, precompiledViews);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Internal for unit testing
|
|
||||||
internal static Dictionary<string, Type> GetPrecompiledViews(
|
|
||||||
IEnumerable<RazorFileInfoCollection> razorFileInfoCollections,
|
|
||||||
IAssemblyLoadContext loadContext)
|
|
||||||
{
|
|
||||||
var precompiledViews = new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
foreach (var viewCollection in razorFileInfoCollections)
|
|
||||||
{
|
|
||||||
var containingAssembly = viewCollection.LoadAssembly(loadContext);
|
|
||||||
foreach (var fileInfo in viewCollection.FileInfos)
|
|
||||||
{
|
|
||||||
var viewType = containingAssembly.GetType(fileInfo.FullTypeName);
|
|
||||||
precompiledViews[fileInfo.RelativePath] = viewType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return precompiledViews;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IEnumerable<RazorFileInfoCollection> GetFileInfoCollections(IEnumerable<Assembly> assemblies)
|
|
||||||
{
|
|
||||||
return assemblies
|
|
||||||
.SelectMany(assembly => assembly.ExportedTypes)
|
|
||||||
.Where(IsValidRazorFileInfoCollection)
|
|
||||||
.Select(Activator.CreateInstance)
|
|
||||||
.Cast<RazorFileInfoCollection>();
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static bool IsValidRazorFileInfoCollection(Type type)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
RazorFileInfoCollectionType.IsAssignableFrom(type) &&
|
|
||||||
!type.GetTypeInfo().IsAbstract &&
|
|
||||||
!type.GetTypeInfo().ContainsGenericParameters;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -73,28 +73,5 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||||
|
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IMvcBuilder AddPrecompiledRazorViews(
|
|
||||||
this IMvcBuilder builder,
|
|
||||||
params Assembly[] assemblies)
|
|
||||||
{
|
|
||||||
if (builder == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(builder));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (assemblies == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(assemblies));
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.Services.Replace(
|
|
||||||
ServiceDescriptor.Singleton<ICompilerCacheProvider>(serviceProvider =>
|
|
||||||
ActivatorUtilities.CreateInstance<PrecompiledViewsCompilerCacheProvider>(
|
|
||||||
serviceProvider,
|
|
||||||
assemblies.AsEnumerable())));
|
|
||||||
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,31 +58,6 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IMvcCoreBuilder AddPrecompiledRazorViews(
|
|
||||||
this IMvcCoreBuilder builder,
|
|
||||||
params Assembly[] assemblies)
|
|
||||||
{
|
|
||||||
if (builder == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(builder));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (assemblies == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(assemblies));
|
|
||||||
}
|
|
||||||
|
|
||||||
AddRazorViewEngine(builder);
|
|
||||||
|
|
||||||
builder.Services.Replace(
|
|
||||||
ServiceDescriptor.Singleton<ICompilerCacheProvider>(serviceProvider =>
|
|
||||||
ActivatorUtilities.CreateInstance<PrecompiledViewsCompilerCacheProvider>(
|
|
||||||
serviceProvider,
|
|
||||||
assemblies.AsEnumerable())));
|
|
||||||
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds an initialization callback for a given <typeparamref name="TTagHelper"/>.
|
/// Adds an initialization callback for a given <typeparamref name="TTagHelper"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -1,76 +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.Runtime.CompilerServices;
|
|
||||||
using System.Text;
|
|
||||||
using Microsoft.AspNet.Mvc.Razor.Precompilation;
|
|
||||||
using Microsoft.Extensions.PlatformAbstractions;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Razor.Internal
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Utility type to code generate <see cref="RazorFileInfoCollection"/> types.
|
|
||||||
/// </summary>
|
|
||||||
public static class RazorFileInfoCollectionGenerator
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Generates CSharp code for the specified <paramref name="fileInfoCollection"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="fileInfoCollection">The <see cref="RazorFileInfoCollection"/>.</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static string GenerateCode(RazorFileInfoCollection fileInfoCollection)
|
|
||||||
{
|
|
||||||
if (fileInfoCollection == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,54 +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.Linq;
|
|
||||||
using Microsoft.AspNet.Razor.CodeGenerators;
|
|
||||||
using Microsoft.CodeAnalysis;
|
|
||||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Razor.Precompilation
|
|
||||||
{
|
|
||||||
public static class GeneratorResultExtensions
|
|
||||||
{
|
|
||||||
public static string GetMainClassName(
|
|
||||||
this GeneratorResults results,
|
|
||||||
IMvcRazorHost host,
|
|
||||||
SyntaxTree syntaxTree)
|
|
||||||
{
|
|
||||||
if (results == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(results));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (host == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(host));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (syntaxTree == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(syntaxTree));
|
|
||||||
}
|
|
||||||
|
|
||||||
// The mainClass name should return directly from the generator results.
|
|
||||||
var classes = syntaxTree.GetRoot().DescendantNodes().OfType<ClassDeclarationSyntax>();
|
|
||||||
var mainClass = classes.FirstOrDefault(c =>
|
|
||||||
c.Identifier.ValueText.StartsWith(host.MainClassNamePrefix, StringComparison.Ordinal));
|
|
||||||
|
|
||||||
if (mainClass != null)
|
|
||||||
{
|
|
||||||
var typeName = mainClass.Identifier.ValueText;
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(host.DefaultNamespace))
|
|
||||||
{
|
|
||||||
typeName = host.DefaultNamespace + "." + typeName;
|
|
||||||
}
|
|
||||||
|
|
||||||
return typeName;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 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 Microsoft.CodeAnalysis;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Razor.Precompilation
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// An entry in the cache used by <see cref="RazorPreCompiler"/>.
|
|
||||||
/// </summary>
|
|
||||||
public class PrecompilationCacheEntry
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of <see cref="PrecompilationCacheEntry"/> for a successful parse.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="fileInfo">The <see cref="RazorFileInfo"/> of the file being cached.</param>
|
|
||||||
/// <param name="syntaxTree">The <see cref="CodeAnalysis.SyntaxTree"/> to cache.</param>
|
|
||||||
public PrecompilationCacheEntry(
|
|
||||||
RazorFileInfo fileInfo,
|
|
||||||
SyntaxTree syntaxTree)
|
|
||||||
{
|
|
||||||
if (fileInfo == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(fileInfo));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (syntaxTree == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(syntaxTree));
|
|
||||||
}
|
|
||||||
|
|
||||||
FileInfo = fileInfo;
|
|
||||||
SyntaxTree = syntaxTree;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes a new instance of <see cref="PrecompilationCacheEntry"/> for a failed parse.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="diagnostics">The <see cref="IReadOnlyList{Diagnostic}"/> produced from parsing the Razor
|
|
||||||
/// file. This does not contain <see cref="Diagnostic"/>s produced from compiling the parsed
|
|
||||||
/// <see cref="CodeAnalysis.SyntaxTree"/>.</param>
|
|
||||||
public PrecompilationCacheEntry(IReadOnlyList<Diagnostic> diagnostics)
|
|
||||||
{
|
|
||||||
if (diagnostics == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(diagnostics));
|
|
||||||
}
|
|
||||||
|
|
||||||
Diagnostics = diagnostics;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the <see cref="RazorFileInfo"/> associated with this cache entry instance.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// This property is not <c>null</c> if <see cref="Success"/> is <c>true</c>.
|
|
||||||
/// </remarks>
|
|
||||||
public RazorFileInfo FileInfo { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the <see cref="SyntaxTree"/> produced from parsing the Razor file.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// This property is not <c>null</c> if <see cref="Success"/> is <c>true</c>.
|
|
||||||
/// </remarks>
|
|
||||||
public SyntaxTree SyntaxTree { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the <see cref="Diagnostic"/>s produced from parsing the generated contents of the file
|
|
||||||
/// specified by <see cref="FileInfo"/>. This does not contain <see cref="Diagnostic"/>s produced from
|
|
||||||
/// compiling the parsed <see cref="CodeAnalysis.SyntaxTree"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// This property is <c>null</c> if <see cref="Success"/> is <c>true</c>.
|
|
||||||
/// </remarks>
|
|
||||||
public IReadOnlyList<Diagnostic> Diagnostics { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets a value that indicates if parsing was successful.
|
|
||||||
/// </summary>
|
|
||||||
public bool Success
|
|
||||||
{
|
|
||||||
get { return SyntaxTree != null; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,47 +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 Microsoft.AspNet.Razor;
|
|
||||||
using Microsoft.CodeAnalysis;
|
|
||||||
using Microsoft.CodeAnalysis.Text;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Razor.Precompilation
|
|
||||||
{
|
|
||||||
public static class RazorErrorExtensions
|
|
||||||
{
|
|
||||||
public static Diagnostic ToDiagnostics(this RazorError error, string filePath)
|
|
||||||
{
|
|
||||||
if (error == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(error));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filePath == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(filePath));
|
|
||||||
}
|
|
||||||
|
|
||||||
var descriptor = new DiagnosticDescriptor(
|
|
||||||
id: "Razor",
|
|
||||||
title: "Razor parsing error",
|
|
||||||
messageFormat: error.Message.Replace("{", "{{").Replace("}", "}}"),
|
|
||||||
category: "Razor.Parser",
|
|
||||||
defaultSeverity: DiagnosticSeverity.Error,
|
|
||||||
isEnabledByDefault: true);
|
|
||||||
|
|
||||||
var location = error.Location;
|
|
||||||
if (location.Equals(SourceLocation.Undefined))
|
|
||||||
{
|
|
||||||
location = SourceLocation.Zero;
|
|
||||||
}
|
|
||||||
var length = Math.Max(0, error.Length);
|
|
||||||
|
|
||||||
var textSpan = new TextSpan(location.AbsoluteIndex, length);
|
|
||||||
var linePositionStart = new LinePosition(location.LineIndex, location.CharacterIndex);
|
|
||||||
var linePositionEnd = new LinePosition(location.LineIndex, location.CharacterIndex + length);
|
|
||||||
var linePositionSpan = new LinePositionSpan(linePositionStart, linePositionEnd);
|
|
||||||
return Diagnostic.Create(descriptor, Location.Create(filePath, textSpan, linePositionSpan));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +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.
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Razor.Precompilation
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Metadata for precompiled files.
|
|
||||||
/// </summary>
|
|
||||||
public class RazorFileInfo
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Type name including namespace.
|
|
||||||
/// </summary>
|
|
||||||
public string FullTypeName { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Path to to the file relative to the application base.
|
|
||||||
/// </summary>
|
|
||||||
public string RelativePath { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,63 +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.Reflection;
|
|
||||||
using Microsoft.Extensions.PlatformAbstractions;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Razor.Precompilation
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Specifies metadata about precompiled views.
|
|
||||||
/// </summary>
|
|
||||||
public abstract class RazorFileInfoCollection
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the name of the resource containing the precompiled binary.
|
|
||||||
/// </summary>
|
|
||||||
public string AssemblyResourceName { get; protected set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the name of the resource that contains the symbols (pdb).
|
|
||||||
/// </summary>
|
|
||||||
public string SymbolsResourceName { get; protected set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the <see cref="IReadOnlyList{T}"/> of <see cref="RazorFileInfo"/>s.
|
|
||||||
/// </summary>
|
|
||||||
public IReadOnlyList<RazorFileInfo> FileInfos { get; protected set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Loads the assembly containing precompiled views.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="loadContext">The <see cref="IAssemblyLoadContext"/>.</param>
|
|
||||||
/// <returns>The <see cref="Assembly"/> containing precompiled views.</returns>
|
|
||||||
public virtual Assembly LoadAssembly(IAssemblyLoadContext loadContext)
|
|
||||||
{
|
|
||||||
var viewCollectionAssembly = GetType().GetTypeInfo().Assembly;
|
|
||||||
|
|
||||||
using (var assemblyStream = viewCollectionAssembly.GetManifestResourceStream(AssemblyResourceName))
|
|
||||||
{
|
|
||||||
if (assemblyStream == null)
|
|
||||||
{
|
|
||||||
var message = Resources.FormatRazorFileInfoCollection_ResourceCouldNotBeFound(AssemblyResourceName,
|
|
||||||
GetType().FullName);
|
|
||||||
throw new InvalidOperationException(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream symbolsStream = null;
|
|
||||||
if (!string.IsNullOrEmpty(SymbolsResourceName))
|
|
||||||
{
|
|
||||||
symbolsStream = viewCollectionAssembly.GetManifestResourceStream(SymbolsResourceName);
|
|
||||||
}
|
|
||||||
|
|
||||||
using (symbolsStream)
|
|
||||||
{
|
|
||||||
return loadContext.LoadStream(assemblyStream, symbolsStream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,121 +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.Runtime.Versioning;
|
|
||||||
using Microsoft.AspNet.FileProviders;
|
|
||||||
using Microsoft.Dnx.Compilation.CSharp;
|
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
|
||||||
using Microsoft.Extensions.Internal;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Razor.Precompilation
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// An <see cref="ICompileModule"/> implementation that pre-compiles Razor views in the application.
|
|
||||||
/// </summary>
|
|
||||||
public abstract class RazorPreCompileModule : ICompileModule
|
|
||||||
{
|
|
||||||
private const string ReleaseConfiguration = "release";
|
|
||||||
private readonly object _memoryCacheLookupLock = new object();
|
|
||||||
private readonly Dictionary<PrecompilationCacheKey, MemoryCache> _memoryCacheLookup =
|
|
||||||
new Dictionary<PrecompilationCacheKey, MemoryCache>();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value that determines if symbols (.pdb) file for the precompiled views is generated.
|
|
||||||
/// </summary>
|
|
||||||
public bool GenerateSymbols { get; protected set; }
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
/// <remarks>Pre-compiles all Razor views in the application.</remarks>
|
|
||||||
public virtual void BeforeCompile(BeforeCompileContext context)
|
|
||||||
{
|
|
||||||
if (!EnablePreCompilation(context))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MemoryCache memoryCache;
|
|
||||||
lock (_memoryCacheLookupLock)
|
|
||||||
{
|
|
||||||
var cacheKey = new PrecompilationCacheKey
|
|
||||||
{
|
|
||||||
Configuration = context.ProjectContext.Configuration,
|
|
||||||
TargetFramework = context.ProjectContext.TargetFramework
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!_memoryCacheLookup.TryGetValue(cacheKey, out memoryCache))
|
|
||||||
{
|
|
||||||
// When CompactOnMemoryPressure is true, the MemoryCache evicts items at every gen2 collection.
|
|
||||||
// In DTH, gen2 happens frequently enough to make it undesirable for caching precompilation results. We'll
|
|
||||||
// disable listening for memory pressure for the MemoryCache instance used by precompilation.
|
|
||||||
memoryCache = new MemoryCache(new MemoryCacheOptions { CompactOnMemoryPressure = false });
|
|
||||||
|
|
||||||
_memoryCacheLookup[cacheKey] = memoryCache;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
using (var fileProvider = new PhysicalFileProvider(context.ProjectContext.ProjectDirectory))
|
|
||||||
{
|
|
||||||
var viewCompiler = new RazorPreCompiler(
|
|
||||||
context,
|
|
||||||
fileProvider,
|
|
||||||
memoryCache)
|
|
||||||
{
|
|
||||||
GenerateSymbols = GenerateSymbols
|
|
||||||
};
|
|
||||||
|
|
||||||
viewCompiler.CompileViews();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void AfterCompile(AfterCompileContext context)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Determines if this instance of <see cref="RazorPreCompileModule"/> should enable
|
|
||||||
/// compilation of views.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="context">The <see cref="BeforeCompileContext"/>.</param>
|
|
||||||
/// <returns><c>true</c> if views should be precompiled; otherwise <c>false</c>.</returns>
|
|
||||||
/// <remarks>Returns <c>true</c> if the current application is being built in <c>release</c>
|
|
||||||
/// configuration.</remarks>
|
|
||||||
protected virtual bool EnablePreCompilation(BeforeCompileContext context)
|
|
||||||
{
|
|
||||||
if (context == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(context));
|
|
||||||
}
|
|
||||||
|
|
||||||
return string.Equals(
|
|
||||||
context.ProjectContext.Configuration,
|
|
||||||
ReleaseConfiguration,
|
|
||||||
StringComparison.OrdinalIgnoreCase);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class PrecompilationCacheKey : IEquatable<PrecompilationCacheKey>
|
|
||||||
{
|
|
||||||
public string Configuration { get; set; }
|
|
||||||
|
|
||||||
public FrameworkName TargetFramework { get; set; }
|
|
||||||
|
|
||||||
public bool Equals(PrecompilationCacheKey other)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
other.TargetFramework == TargetFramework &&
|
|
||||||
string.Equals(other.Configuration, Configuration, StringComparison.Ordinal);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
|
||||||
{
|
|
||||||
var hashCodeCombiner = HashCodeCombiner.Start();
|
|
||||||
hashCodeCombiner.Add(Configuration);
|
|
||||||
hashCodeCombiner.Add(TargetFramework);
|
|
||||||
|
|
||||||
return hashCodeCombiner;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,356 +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.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
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.CSharp;
|
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
|
||||||
using Microsoft.Extensions.CompilationAbstractions;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Razor.Precompilation
|
|
||||||
{
|
|
||||||
public class RazorPreCompiler
|
|
||||||
{
|
|
||||||
private const string CacheKeyDirectorySeparator = "/";
|
|
||||||
private readonly TagHelperDescriptorFactory _tagHelperDescriptorFactory =
|
|
||||||
new TagHelperDescriptorFactory(designTime: false);
|
|
||||||
|
|
||||||
public RazorPreCompiler(
|
|
||||||
BeforeCompileContext compileContext,
|
|
||||||
IFileProvider fileProvider,
|
|
||||||
IMemoryCache precompilationCache)
|
|
||||||
{
|
|
||||||
if (compileContext == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(compileContext));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fileProvider == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(fileProvider));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (precompilationCache == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(precompilationCache));
|
|
||||||
}
|
|
||||||
|
|
||||||
CompileContext = compileContext;
|
|
||||||
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,
|
|
||||||
Defines = defines,
|
|
||||||
LanguageVersion = compileContext.Compilation.LanguageVersion
|
|
||||||
};
|
|
||||||
PreCompilationCache = precompilationCache;
|
|
||||||
TagHelperTypeResolver = new PrecompilationTagHelperTypeResolver(CompileContext.Compilation);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value that determines if symbols (.pdb) file for the precompiled views is generated.
|
|
||||||
/// </summary>
|
|
||||||
public bool GenerateSymbols { get; set; }
|
|
||||||
|
|
||||||
protected IFileProvider FileProvider { get; }
|
|
||||||
|
|
||||||
protected BeforeCompileContext CompileContext { get; }
|
|
||||||
|
|
||||||
protected CompilationSettings CompilationSettings { get; }
|
|
||||||
|
|
||||||
protected IMemoryCache PreCompilationCache { get; }
|
|
||||||
|
|
||||||
protected virtual string FileExtension { get; } = ".cshtml";
|
|
||||||
|
|
||||||
protected virtual int MaxDegreesOfParallelism { get; } = Environment.ProcessorCount;
|
|
||||||
|
|
||||||
protected virtual TagHelperTypeResolver TagHelperTypeResolver { get; }
|
|
||||||
|
|
||||||
public virtual void CompileViews()
|
|
||||||
{
|
|
||||||
var result = CreateFileInfoCollection();
|
|
||||||
if (result != null)
|
|
||||||
{
|
|
||||||
var generatedCode = RazorFileInfoCollectionGenerator.GenerateCode(result);
|
|
||||||
var syntaxTree = CSharpSyntaxTree.ParseText(
|
|
||||||
generatedCode,
|
|
||||||
SyntaxTreeGenerator.GetParseOptions(CompilationSettings));
|
|
||||||
CompileContext.Compilation = CompileContext.Compilation.AddSyntaxTrees(syntaxTree);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual RazorFileInfoCollection CreateFileInfoCollection()
|
|
||||||
{
|
|
||||||
var filesToProcess = new List<RelativeFileInfo>();
|
|
||||||
GetFileInfosRecursive(root: string.Empty, razorFiles: filesToProcess);
|
|
||||||
if (filesToProcess.Count == 0)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var razorFiles = new RazorFileInfo[filesToProcess.Count];
|
|
||||||
var syntaxTrees = new SyntaxTree[filesToProcess.Count];
|
|
||||||
var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = MaxDegreesOfParallelism };
|
|
||||||
var diagnosticsLock = new object();
|
|
||||||
var hasErrors = false;
|
|
||||||
|
|
||||||
Parallel.For(0, filesToProcess.Count, parallelOptions, index =>
|
|
||||||
{
|
|
||||||
var file = filesToProcess[index];
|
|
||||||
|
|
||||||
PrecompilationCacheEntry cacheEntry;
|
|
||||||
if (!PreCompilationCache.TryGetValue(file.RelativePath, out cacheEntry))
|
|
||||||
{
|
|
||||||
cacheEntry = GetCacheEntry(file);
|
|
||||||
PreCompilationCache.Set(
|
|
||||||
file.RelativePath,
|
|
||||||
cacheEntry,
|
|
||||||
GetMemoryCacheEntryOptions(file, cacheEntry));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cacheEntry != null)
|
|
||||||
{
|
|
||||||
if (cacheEntry.Success)
|
|
||||||
{
|
|
||||||
syntaxTrees[index] = cacheEntry.SyntaxTree;
|
|
||||||
razorFiles[index] = cacheEntry.FileInfo;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hasErrors = true;
|
|
||||||
lock (diagnosticsLock)
|
|
||||||
{
|
|
||||||
AddRange(CompileContext.Diagnostics, cacheEntry.Diagnostics);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (hasErrors)
|
|
||||||
{
|
|
||||||
// If any of the Razor files had syntax errors, don't emit the precompiled views assembly.
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GeneratePrecompiledAssembly(
|
|
||||||
syntaxTrees.Where(tree => tree != null),
|
|
||||||
razorFiles.Where(file => file != null));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual RazorFileInfoCollection GeneratePrecompiledAssembly(
|
|
||||||
IEnumerable<SyntaxTree> syntaxTrees,
|
|
||||||
IEnumerable<RazorFileInfo> razorFileInfos)
|
|
||||||
{
|
|
||||||
if (syntaxTrees == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(syntaxTrees));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (razorFileInfos == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(razorFileInfos));
|
|
||||||
}
|
|
||||||
|
|
||||||
var resourcePrefix = string.Join(".", CompileContext.Compilation.AssemblyName,
|
|
||||||
nameof(RazorPreCompiler),
|
|
||||||
Path.GetRandomFileName());
|
|
||||||
var assemblyResourceName = resourcePrefix + ".dll";
|
|
||||||
|
|
||||||
|
|
||||||
var applicationReference = CompileContext.Compilation.ToMetadataReference();
|
|
||||||
var references = CompileContext.Compilation.References
|
|
||||||
.Concat(new[] { applicationReference });
|
|
||||||
|
|
||||||
var preCompilationOptions = CompilationSettings
|
|
||||||
.CompilationOptions
|
|
||||||
.WithOutputKind(OutputKind.DynamicallyLinkedLibrary);
|
|
||||||
|
|
||||||
var compilation = CSharpCompilation.Create(
|
|
||||||
assemblyResourceName,
|
|
||||||
options: preCompilationOptions,
|
|
||||||
syntaxTrees: syntaxTrees,
|
|
||||||
references: references);
|
|
||||||
|
|
||||||
var generateSymbols = GenerateSymbols && SymbolsUtility.SupportsSymbolsGeneration();
|
|
||||||
// These streams are returned to the runtime and consequently cannot be disposed.
|
|
||||||
var assemblyStream = new MemoryStream();
|
|
||||||
var pdbStream = generateSymbols ? new MemoryStream() : null;
|
|
||||||
var emitResult = compilation.Emit(assemblyStream, pdbStream);
|
|
||||||
if (!emitResult.Success)
|
|
||||||
{
|
|
||||||
AddRange(CompileContext.Diagnostics, emitResult.Diagnostics);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var assemblyResource = new ResourceDescriptor()
|
|
||||||
{
|
|
||||||
FileName = Path.GetFileName(assemblyResourceName),
|
|
||||||
Name = assemblyResourceName,
|
|
||||||
StreamFactory = () => GetNonDisposableStream(assemblyStream)
|
|
||||||
};
|
|
||||||
CompileContext.Resources.Add(assemblyResource);
|
|
||||||
|
|
||||||
string symbolsResourceName = null;
|
|
||||||
if (pdbStream != null)
|
|
||||||
{
|
|
||||||
symbolsResourceName = resourcePrefix + ".pdb";
|
|
||||||
var pdbResource = new ResourceDescriptor()
|
|
||||||
{
|
|
||||||
FileName = Path.GetFileName(symbolsResourceName),
|
|
||||||
Name = symbolsResourceName,
|
|
||||||
StreamFactory = () => GetNonDisposableStream(pdbStream)
|
|
||||||
};
|
|
||||||
|
|
||||||
CompileContext.Resources.Add(pdbResource);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new PrecompileRazorFileInfoCollection(assemblyResourceName,
|
|
||||||
symbolsResourceName,
|
|
||||||
razorFileInfos.ToList());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected IMvcRazorHost GetRazorHost()
|
|
||||||
{
|
|
||||||
var descriptorResolver = new TagHelperDescriptorResolver(
|
|
||||||
TagHelperTypeResolver,
|
|
||||||
_tagHelperDescriptorFactory);
|
|
||||||
return new MvcRazorHost(new DefaultChunkTreeCache(FileProvider))
|
|
||||||
{
|
|
||||||
TagHelperDescriptorResolver = descriptorResolver
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private MemoryCacheEntryOptions GetMemoryCacheEntryOptions(
|
|
||||||
RelativeFileInfo fileInfo,
|
|
||||||
PrecompilationCacheEntry cacheEntry)
|
|
||||||
{
|
|
||||||
var options = new MemoryCacheEntryOptions();
|
|
||||||
options.AddExpirationToken(FileProvider.Watch(fileInfo.RelativePath));
|
|
||||||
foreach (var path in ViewHierarchyUtility.GetViewImportsLocations(fileInfo.RelativePath))
|
|
||||||
{
|
|
||||||
options.AddExpirationToken(FileProvider.Watch(path));
|
|
||||||
}
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void GetFileInfosRecursive(string root, List<RelativeFileInfo> razorFiles)
|
|
||||||
{
|
|
||||||
var fileInfos = FileProvider.GetDirectoryContents(root);
|
|
||||||
|
|
||||||
foreach (var fileInfo in fileInfos)
|
|
||||||
{
|
|
||||||
if (fileInfo.IsDirectory)
|
|
||||||
{
|
|
||||||
var subPath = CombinePath(root, fileInfo.Name);
|
|
||||||
GetFileInfosRecursive(subPath, razorFiles);
|
|
||||||
}
|
|
||||||
else if (Path.GetExtension(fileInfo.Name)
|
|
||||||
.Equals(FileExtension, StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
var relativePath = CombinePath(root, fileInfo.Name);
|
|
||||||
var info = new RelativeFileInfo(fileInfo, relativePath);
|
|
||||||
razorFiles.Add(info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual PrecompilationCacheEntry GetCacheEntry(RelativeFileInfo fileInfo)
|
|
||||||
{
|
|
||||||
if (fileInfo == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(fileInfo));
|
|
||||||
}
|
|
||||||
|
|
||||||
using (var stream = fileInfo.FileInfo.CreateReadStream())
|
|
||||||
{
|
|
||||||
using (var host = GetRazorHost())
|
|
||||||
{
|
|
||||||
var results = host.GenerateCode(fileInfo.RelativePath, stream);
|
|
||||||
|
|
||||||
if (results.Success)
|
|
||||||
{
|
|
||||||
var syntaxTree = SyntaxTreeGenerator.Generate(
|
|
||||||
results.GeneratedCode,
|
|
||||||
fileInfo.FileInfo.PhysicalPath,
|
|
||||||
CompilationSettings);
|
|
||||||
var fullTypeName = results.GetMainClassName(host, syntaxTree);
|
|
||||||
|
|
||||||
if (fullTypeName != null)
|
|
||||||
{
|
|
||||||
var razorFileInfo = new RazorFileInfo
|
|
||||||
{
|
|
||||||
RelativePath = fileInfo.RelativePath,
|
|
||||||
FullTypeName = fullTypeName
|
|
||||||
};
|
|
||||||
|
|
||||||
return new PrecompilationCacheEntry(razorFileInfo, syntaxTree);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var diagnostics = results
|
|
||||||
.ParserErrors
|
|
||||||
.Select(error => error.ToDiagnostics(fileInfo.FileInfo.PhysicalPath))
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
return new PrecompilationCacheEntry(diagnostics);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void AddRange<TVal>(IList<TVal> target, IEnumerable<TVal> source)
|
|
||||||
{
|
|
||||||
foreach (var diagnostic in source)
|
|
||||||
{
|
|
||||||
target.Add(diagnostic);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Stream GetNonDisposableStream(Stream stream)
|
|
||||||
{
|
|
||||||
stream.Position = 0;
|
|
||||||
return new NonDisposableStream(stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string CombinePath(string root, string name)
|
|
||||||
{
|
|
||||||
// We use string.Join instead of Path.Combine here to ensure that the path
|
|
||||||
// separator we produce matches the one used by the CompilerCache.
|
|
||||||
return string.Join(CacheKeyDirectorySeparator, root, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class PrecompileRazorFileInfoCollection : RazorFileInfoCollection
|
|
||||||
{
|
|
||||||
public PrecompileRazorFileInfoCollection(
|
|
||||||
string assemblyResourceName,
|
|
||||||
string symbolsResourceName,
|
|
||||||
IReadOnlyList<RazorFileInfo> fileInfos)
|
|
||||||
{
|
|
||||||
AssemblyResourceName = assemblyResourceName;
|
|
||||||
SymbolsResourceName = symbolsResourceName;
|
|
||||||
FileInfos = fileInfos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -13,7 +13,6 @@
|
||||||
"Microsoft.AspNet.FileProviders.Composite": "1.0.0-*",
|
"Microsoft.AspNet.FileProviders.Composite": "1.0.0-*",
|
||||||
"Microsoft.AspNet.Mvc.Razor.Host": "6.0.0-*",
|
"Microsoft.AspNet.Mvc.Razor.Host": "6.0.0-*",
|
||||||
"Microsoft.AspNet.Mvc.ViewFeatures": "6.0.0-*",
|
"Microsoft.AspNet.Mvc.ViewFeatures": "6.0.0-*",
|
||||||
"Microsoft.AspNet.Razor.Runtime.Precompilation": "4.0.0-*",
|
|
||||||
"Microsoft.Extensions.HashCodeCombiner.Sources": {
|
"Microsoft.Extensions.HashCodeCombiner.Sources": {
|
||||||
"version": "1.0.0-*",
|
"version": "1.0.0-*",
|
||||||
"type": "build"
|
"type": "build"
|
||||||
|
|
|
@ -1,137 +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.Linq;
|
|
||||||
using System.Net;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNet.Mvc.Razor.Precompilation;
|
|
||||||
using Microsoft.AspNet.Testing.xunit;
|
|
||||||
using PrecompilationWebSite;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.FunctionalTests
|
|
||||||
{
|
|
||||||
public class PrecompilationTest : IClassFixture<MvcTestFixture<PrecompilationWebSite.Startup>>
|
|
||||||
{
|
|
||||||
public PrecompilationTest(MvcTestFixture<PrecompilationWebSite.Startup> fixture)
|
|
||||||
{
|
|
||||||
Client = fixture.Client;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HttpClient Client { get; }
|
|
||||||
|
|
||||||
[ConditionalFact]
|
|
||||||
[FrameworkSkipCondition(RuntimeFrameworks.Mono)]
|
|
||||||
public async Task PrecompiledView_RendersCorrectly()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
// We will render a view that writes the fully qualified name of the Assembly containing the type of
|
|
||||||
// the view. If the view is precompiled, this assembly will be PrecompilationWebsite.
|
|
||||||
var assemblyNamePrefix = GetAssemblyNamePrefix();
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var response = await Client.GetAsync("http://localhost/Home/Index");
|
|
||||||
var responseContent = await response.Content.ReadAsStringAsync();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
|
||||||
var parsedResponse1 = new ParsedResponse(responseContent);
|
|
||||||
Assert.StartsWith(assemblyNamePrefix, parsedResponse1.ViewStart);
|
|
||||||
Assert.StartsWith(assemblyNamePrefix, parsedResponse1.Layout);
|
|
||||||
Assert.StartsWith(assemblyNamePrefix, parsedResponse1.Index);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task PrecompiledView_UsesCompilationOptionsFromApplication()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var assemblyNamePrefix = GetAssemblyNamePrefix();
|
|
||||||
#if DNX451
|
|
||||||
var expected =
|
|
||||||
@"Value set inside DNX451 " + assemblyNamePrefix;
|
|
||||||
#elif DNXCORE50
|
|
||||||
var expected =
|
|
||||||
@"Value set inside DNXCORE50 " + assemblyNamePrefix;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var response = await Client.GetAsync("http://localhost/Home/PrecompiledViewsCanConsumeCompilationOptions");
|
|
||||||
var responseContent = await response.Content.ReadAsStringAsync();
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.StartsWith(expected, responseContent.Trim());
|
|
||||||
}
|
|
||||||
|
|
||||||
[ConditionalFact]
|
|
||||||
[FrameworkSkipCondition(RuntimeFrameworks.Mono)]
|
|
||||||
public async Task TagHelpersFromTheApplication_CanBeAdded()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var assemblyNamePrefix = GetAssemblyNamePrefix();
|
|
||||||
var expected =
|
|
||||||
@"<root data-root=""true""><input class=""form-control"" type=""number"" data-val=""true""" +
|
|
||||||
@" data-val-range=""The field Age must be between 10 and 100."" data-val-range-max=""100"" "+
|
|
||||||
@"data-val-range-min=""10"" data-val-required=""The Age field is required."" " +
|
|
||||||
@"id=""Age"" name=""Age"" value="""" /><a href=""/TagHelpers"">Back to List</a></root>";
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var response = await Client.GetStringAsync("http://localhost/TagHelpers/Add");
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
var responseLines = response.Split(new[] { "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
Assert.StartsWith(assemblyNamePrefix, responseLines[0]);
|
|
||||||
Assert.Equal(expected, responseLines[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
[ConditionalFact]
|
|
||||||
[FrameworkSkipCondition(RuntimeFrameworks.Mono)]
|
|
||||||
public async Task TagHelpersFromTheApplication_CanBeRemoved()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var assemblyNamePrefix = GetAssemblyNamePrefix();
|
|
||||||
var expected = @"<root>root-content</root>";
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var response = await Client.GetStringAsync("http://localhost/TagHelpers/Remove");
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
var responseLines = response.Split(new[] { "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
Assert.StartsWith(assemblyNamePrefix, responseLines[0]);
|
|
||||||
Assert.Equal(expected, responseLines[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetAssemblyNamePrefix()
|
|
||||||
{
|
|
||||||
return typeof(Startup).GetTypeInfo().Assembly.GetName().Name + "." + nameof(RazorPreCompiler) + ".";
|
|
||||||
}
|
|
||||||
|
|
||||||
private sealed class ParsedResponse
|
|
||||||
{
|
|
||||||
public ParsedResponse(string responseContent)
|
|
||||||
{
|
|
||||||
var results = responseContent
|
|
||||||
.Split(new[] { "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries)
|
|
||||||
.Select(s => s.Trim())
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
Assert.True(results[0].StartsWith("Layout:"));
|
|
||||||
Layout = results[0].Substring("Layout:".Length);
|
|
||||||
|
|
||||||
Assert.True(results[1].StartsWith("_viewstart:"));
|
|
||||||
ViewStart = results[1].Substring("_viewstart:".Length);
|
|
||||||
|
|
||||||
Assert.True(results[2].StartsWith("index:"));
|
|
||||||
Index = results[2].Substring("index:".Length);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Layout { get; }
|
|
||||||
|
|
||||||
public string ViewStart { get; }
|
|
||||||
|
|
||||||
public string Index { get; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -37,7 +37,6 @@
|
||||||
"Microsoft.Extensions.Logging.Testing": "1.0.0-*",
|
"Microsoft.Extensions.Logging.Testing": "1.0.0-*",
|
||||||
"MvcSandbox": "1.0.0",
|
"MvcSandbox": "1.0.0",
|
||||||
"MvcSubAreaSample.Web": "1.0.0",
|
"MvcSubAreaSample.Web": "1.0.0",
|
||||||
"PrecompilationWebSite": "1.0.0",
|
|
||||||
"RazorPageExecutionInstrumentationWebSite": "1.0.0",
|
"RazorPageExecutionInstrumentationWebSite": "1.0.0",
|
||||||
"RazorWebSite": "1.0.0",
|
"RazorWebSite": "1.0.0",
|
||||||
"RoutingWebSite": "1.0.0",
|
"RoutingWebSite": "1.0.0",
|
||||||
|
|
|
@ -1,142 +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.Reflection;
|
|
||||||
using Microsoft.AspNet.Mvc.Razor.Precompilation;
|
|
||||||
using Microsoft.Extensions.PlatformAbstractions;
|
|
||||||
using Moq;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Razor.Compilation
|
|
||||||
{
|
|
||||||
public class PrecompiledViewsCompilerCacheProviderTest
|
|
||||||
{
|
|
||||||
[Fact]
|
|
||||||
public void IsValidRazorFileInfoCollection_ReturnsFalse_IfTypeIsAbstract()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var type = typeof(AbstractRazorFileInfoCollection);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var result = PrecompiledViewsCompilerCacheProvider.IsValidRazorFileInfoCollection(type);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.False(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void IsValidRazorFileInfoCollection_ReturnsFalse_IfTypeHasGenericParameters()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var type = typeof(GenericRazorFileInfoCollection<>);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var result = PrecompiledViewsCompilerCacheProvider.IsValidRazorFileInfoCollection(type);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.False(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void IsValidRazorFileInfoCollection_ReturnsFalse_IfTypeDoesNotDeriveFromRazorFileInfoCollection()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var type = typeof(NonSubTypeRazorFileInfoCollection);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var result = PrecompiledViewsCompilerCacheProvider.IsValidRazorFileInfoCollection(type);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.False(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[InlineData(typeof(ParameterConstructorRazorFileInfoCollection))]
|
|
||||||
[InlineData(typeof(ViewCollection))]
|
|
||||||
public void IsValidRazorFileInfoCollection_ReturnsTrue_IfTypeDerivesFromRazorFileInfoCollection(Type type)
|
|
||||||
{
|
|
||||||
// Act
|
|
||||||
var result = PrecompiledViewsCompilerCacheProvider.IsValidRazorFileInfoCollection(type);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.True(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void GetPrecompiledViews_ReturnsTypesSpecifiedByRazorFileInfoCollections()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var fileInfoCollections = new[] { new ViewCollection() };
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var precompiledViews = PrecompiledViewsCompilerCacheProvider.GetPrecompiledViews(
|
|
||||||
fileInfoCollections,
|
|
||||||
Mock.Of<IAssemblyLoadContext>());
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Equal(2, precompiledViews.Count);
|
|
||||||
|
|
||||||
Type type;
|
|
||||||
Assert.True(precompiledViews.TryGetValue("Views/Home/Index.cshtml", out type));
|
|
||||||
Assert.Equal(typeof(TestView1), type);
|
|
||||||
|
|
||||||
Assert.True(precompiledViews.TryGetValue("Views/Home/About.cshtml", out type));
|
|
||||||
Assert.Equal(typeof(TestView2), type);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private abstract class AbstractRazorFileInfoCollection : RazorFileInfoCollection
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private class GenericRazorFileInfoCollection<TVal> : RazorFileInfoCollection
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ParameterConstructorRazorFileInfoCollection : RazorFileInfoCollection
|
|
||||||
{
|
|
||||||
public ParameterConstructorRazorFileInfoCollection(string value)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class NonSubTypeRazorFileInfoCollection : Controller
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ViewCollection : RazorFileInfoCollection
|
|
||||||
{
|
|
||||||
public ViewCollection()
|
|
||||||
{
|
|
||||||
FileInfos = new[]
|
|
||||||
{
|
|
||||||
new RazorFileInfo
|
|
||||||
{
|
|
||||||
FullTypeName = typeof(TestView1).FullName,
|
|
||||||
RelativePath = "Views/Home/Index.cshtml"
|
|
||||||
},
|
|
||||||
new RazorFileInfo
|
|
||||||
{
|
|
||||||
FullTypeName = typeof(TestView2).FullName,
|
|
||||||
RelativePath = "Views/Home/About.cshtml"
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Assembly LoadAssembly(IAssemblyLoadContext loadContext)
|
|
||||||
{
|
|
||||||
return GetType().GetTypeInfo().Assembly;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private class TestView1
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TestView2
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,135 +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.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<Microsoft.AspNet.Mvc.Razor.Precompilation.RazorFileInfo>
|
|
||||||
{
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private static System.Reflection.Assembly _loadedAssembly;
|
|
||||||
|
|
||||||
public override System.Reflection.Assembly LoadAssembly(
|
|
||||||
Microsoft.Extensions.PlatformAbstractions.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<Microsoft.AspNet.Mvc.Razor.Precompilation.RazorFileInfo>
|
|
||||||
{
|
|
||||||
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.Extensions.PlatformAbstractions.IAssemblyLoadContext loadContext)
|
|
||||||
{
|
|
||||||
if (_loadedAssembly == null)
|
|
||||||
{
|
|
||||||
_loadedAssembly = base.LoadAssembly(loadContext);
|
|
||||||
}
|
|
||||||
return _loadedAssembly;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}";
|
|
||||||
|
|
||||||
return new TheoryData<RazorFileInfoCollection, string>
|
|
||||||
{
|
|
||||||
{ 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<RazorFileInfo>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TestCollection : RazorFileInfoCollection
|
|
||||||
{
|
|
||||||
public TestCollection()
|
|
||||||
{
|
|
||||||
AssemblyResourceName = "TestAssembly";
|
|
||||||
SymbolsResourceName = "SymbolsResource";
|
|
||||||
FileInfos = new List<RazorFileInfo>
|
|
||||||
{
|
|
||||||
new RazorFileInfo
|
|
||||||
{
|
|
||||||
FullTypeName = "SomeType.Name",
|
|
||||||
RelativePath = @"Views/Home/Index.cshtml"
|
|
||||||
},
|
|
||||||
new RazorFileInfo
|
|
||||||
{
|
|
||||||
FullTypeName = "Different.Name",
|
|
||||||
RelativePath = @"Views/Home/Different.cshtml"
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,65 +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 Microsoft.AspNet.Razor;
|
|
||||||
using Xunit;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Mvc.Razor.Precompilation
|
|
||||||
{
|
|
||||||
public class RazorErrorExtensionsTest
|
|
||||||
{
|
|
||||||
public static TheoryData ToDiagnostic_SucceedsWhenRazorErrorLocationIsZeroOrUndefinedData
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return new TheoryData<SourceLocation, int>
|
|
||||||
{
|
|
||||||
{ SourceLocation.Undefined, -1 },
|
|
||||||
{ SourceLocation.Undefined, 0 },
|
|
||||||
{ SourceLocation.Zero, -1 },
|
|
||||||
{ SourceLocation.Zero, 0 },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Theory]
|
|
||||||
[MemberData(nameof(ToDiagnostic_SucceedsWhenRazorErrorLocationIsZeroOrUndefinedData))]
|
|
||||||
public void ToDiagnostic_SucceedsWhenRazorErrorLocationIsZeroOrUndefined(
|
|
||||||
SourceLocation location,
|
|
||||||
int length)
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var error = new RazorError("some message", location, length);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var diagnostics = error.ToDiagnostics("/some-path");
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
var span = diagnostics.Location.GetMappedLineSpan();
|
|
||||||
Assert.Equal("/some-path", span.Path);
|
|
||||||
Assert.Equal(0, span.StartLinePosition.Line);
|
|
||||||
Assert.Equal(0, span.StartLinePosition.Character);
|
|
||||||
Assert.Equal(0, span.EndLinePosition.Line);
|
|
||||||
Assert.Equal(0, span.EndLinePosition.Character);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void ToDiagnostic_ConvertsRazorErrorLocation_ToSourceLineMappings()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var sourceLocation = new SourceLocation(absoluteIndex: 30, lineIndex: 10, characterIndex: 1);
|
|
||||||
var error = new RazorError("some message", sourceLocation, length: 5);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var diagnostics = error.ToDiagnostics("/some-path");
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
var span = diagnostics.Location.GetMappedLineSpan();
|
|
||||||
Assert.Equal("/some-path", span.Path);
|
|
||||||
Assert.Equal(10, span.StartLinePosition.Line);
|
|
||||||
Assert.Equal(1, span.StartLinePosition.Character);
|
|
||||||
Assert.Equal(10, span.EndLinePosition.Line);
|
|
||||||
Assert.Equal(6, span.EndLinePosition.Character);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
*.cshtml
|
|
|
@ -1,31 +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 Microsoft.AspNet.Mvc;
|
|
||||||
|
|
||||||
namespace PrecompilationWebSite.Controllers
|
|
||||||
{
|
|
||||||
public class HomeController : Controller
|
|
||||||
{
|
|
||||||
public IActionResult Index()
|
|
||||||
{
|
|
||||||
return View();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IActionResult PrecompiledViewsCanConsumeCompilationOptions()
|
|
||||||
{
|
|
||||||
return View("~/Views/ViewsConsumingCompilationOptions/Index.cshtml");
|
|
||||||
}
|
|
||||||
|
|
||||||
public IActionResult GlobalDeletedPriorToFirstRequest()
|
|
||||||
{
|
|
||||||
return View("~/Views/ViewImportsDelete/Index.cshtml");
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpGet("/Test")]
|
|
||||||
public IActionResult TestView()
|
|
||||||
{
|
|
||||||
return View("~/Views/Test/Index.cshtml");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,20 +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 Microsoft.AspNet.Mvc;
|
|
||||||
|
|
||||||
namespace PrecompilationWebSite.Controllers
|
|
||||||
{
|
|
||||||
public class TagHelpersController : Controller
|
|
||||||
{
|
|
||||||
public IActionResult Add()
|
|
||||||
{
|
|
||||||
return View();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IActionResult Remove()
|
|
||||||
{
|
|
||||||
return View();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +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.ComponentModel.DataAnnotations;
|
|
||||||
|
|
||||||
namespace PrecompilationWebSite.Models
|
|
||||||
{
|
|
||||||
public class Person
|
|
||||||
{
|
|
||||||
[Range(10, 100)]
|
|
||||||
public int Age { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,39 +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.Reflection;
|
|
||||||
using Microsoft.AspNet.Builder;
|
|
||||||
using Microsoft.AspNet.Hosting;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
|
|
||||||
namespace PrecompilationWebSite
|
|
||||||
{
|
|
||||||
public class Startup
|
|
||||||
{
|
|
||||||
// Set up application services
|
|
||||||
public void ConfigureServices(IServiceCollection services)
|
|
||||||
{
|
|
||||||
// Add MVC services to the services container
|
|
||||||
services
|
|
||||||
.AddMvc()
|
|
||||||
.AddPrecompiledRazorViews(GetType().GetTypeInfo().Assembly);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Configure(IApplicationBuilder app)
|
|
||||||
{
|
|
||||||
app.UseCultureReplacer();
|
|
||||||
|
|
||||||
app.UseMvcWithDefaultRoute();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Main(string[] args)
|
|
||||||
{
|
|
||||||
var application = new WebApplicationBuilder()
|
|
||||||
.UseConfiguration(WebApplicationConfiguration.GetDefault(args))
|
|
||||||
.UseStartup<Startup>()
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
application.Run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,16 +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 Microsoft.AspNet.Razor.TagHelpers;
|
|
||||||
|
|
||||||
namespace PrecompilationWebSite.TagHelpers
|
|
||||||
{
|
|
||||||
[HtmlTargetElement("root")]
|
|
||||||
public class RootViewStartTagHelper : TagHelper
|
|
||||||
{
|
|
||||||
public override void Process(TagHelperContext context, TagHelperOutput output)
|
|
||||||
{
|
|
||||||
output.Attributes["data-root"] = "true";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
index:@GetType().GetTypeInfo().Assembly.GetName()
|
|
|
@ -1,2 +0,0 @@
|
||||||
Layout:@GetType().GetTypeInfo().Assembly.FullName
|
|
||||||
@RenderBody()
|
|
|
@ -1 +0,0 @@
|
||||||
@using System.Reflection
|
|
|
@ -1,2 +0,0 @@
|
||||||
@{ Layout = "/Views/Home/Layout.cshtml";}
|
|
||||||
_viewstart:@GetType().GetTypeInfo().Assembly.FullName
|
|
|
@ -1,3 +0,0 @@
|
||||||
@model PrecompilationWebSite.Models.Person
|
|
||||||
@addTagHelper *, Microsoft.AspNet.Mvc.TagHelpers
|
|
||||||
<root><input asp-for="Age" class="form-control" /><a asp-action="Index">Back to List</a></root>
|
|
|
@ -1,2 +0,0 @@
|
||||||
@removeTagHelper *, PrecompilationWebSite
|
|
||||||
<root>root-content</root>
|
|
|
@ -1 +0,0 @@
|
||||||
@addTagHelper PrecompilationWebSite.TagHelpers.RootViewStartTagHelper, PrecompilationWebSite
|
|
|
@ -1,2 +0,0 @@
|
||||||
@using System.Reflection
|
|
||||||
@GetType().GetTypeInfo().Assembly.FullName
|
|
|
@ -1 +0,0 @@
|
||||||
Test
|
|
|
@ -1,2 +0,0 @@
|
||||||
@using System.Reflection;
|
|
||||||
@GetType().GetTypeInfo().Assembly.FullName
|
|
|
@ -1 +0,0 @@
|
||||||
_ViewStart content
|
|
|
@ -1,9 +0,0 @@
|
||||||
@{
|
|
||||||
string message =
|
|
||||||
#if DNX451
|
|
||||||
"Value set inside DNX451 " + GetType().Assembly.FullName;
|
|
||||||
#elif DNXCORE50
|
|
||||||
"Value set inside DNXCORE50 " + System.Reflection.IntrospectionExtensions.GetTypeInfo(GetType()).Assembly.FullName;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
@message
|
|
|
@ -1,13 +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 Microsoft.AspNet.Mvc.Razor.Precompilation;
|
|
||||||
using Microsoft.Dnx.Compilation.CSharp;
|
|
||||||
|
|
||||||
namespace PrecompilationWebSite
|
|
||||||
{
|
|
||||||
public class RazorPreCompilation : RazorPreCompileModule
|
|
||||||
{
|
|
||||||
protected override bool EnablePreCompilation(BeforeCompileContext context) => true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
{
|
|
||||||
"server": "Microsoft.AspNet.Server.Kestrel"
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
{
|
|
||||||
"commands": {
|
|
||||||
"web": "PrecompilationWebSite"
|
|
||||||
},
|
|
||||||
"compilationOptions": {
|
|
||||||
"emitEntryPoint": true
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"Microsoft.AspNet.Mvc": "6.0.0-*",
|
|
||||||
"Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-*",
|
|
||||||
"Microsoft.AspNet.Mvc.TestConfiguration": "1.0.0",
|
|
||||||
"Microsoft.AspNet.Server.Kestrel": "1.0.0-*",
|
|
||||||
"Microsoft.AspNet.StaticFiles": "1.0.0-*",
|
|
||||||
"Microsoft.Extensions.PropertyHelper.Sources": {
|
|
||||||
"version": "1.0.0-*",
|
|
||||||
"type": "build"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"frameworks": {
|
|
||||||
"dnx451": {
|
|
||||||
"compilationOptions": {
|
|
||||||
"define": [ "CUSTOM_DNX451_DEFINE" ]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"dnxcore50": {
|
|
||||||
"compilationOptions": {
|
|
||||||
"define": [ "CUSTOM_DNXCORE50_DEFINE" ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
PreCompilationWebSite
|
|
||||||
===
|
|
||||||
|
|
||||||
This web site illustrates use cases for precompilation of razor pages.
|
|
|
@ -1 +0,0 @@
|
||||||
HelloWorld
|
|
Загрузка…
Ссылка в новой задаче