Making Razor compilation cache replaceable (#7780)

This commit is contained in:
Sébastien Ros 2018-05-15 11:36:47 -07:00 committed by GitHub
parent d9f035ad7c
commit 19d82928ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 40 additions and 3 deletions

View File

@ -0,0 +1,15 @@
// 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.Extensions.Caching.Memory;
namespace Microsoft.AspNetCore.Mvc.Razor.Compilation
{
/// <summary>
/// Provides an instance of <see cref="IMemoryCache"/> that is used to store compiled Razor views.
/// </summary>
public interface IViewCompilationMemoryCacheProvider
{
IMemoryCache CompilationMemoryCache { get; }
}
}

View File

@ -0,0 +1,12 @@
// 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.Extensions.Caching.Memory;
namespace Microsoft.AspNetCore.Mvc.Razor.Compilation
{
internal class RazorViewCompilationMemoryCacheProvider : IViewCompilationMemoryCacheProvider
{
IMemoryCache IViewCompilationMemoryCacheProvider.CompilationMemoryCache { get; } = new MemoryCache(new MemoryCacheOptions());
}
}

View File

@ -172,6 +172,7 @@ namespace Microsoft.Extensions.DependencyInjection
return viewEngine;
});
services.TryAddSingleton<IViewCompilerProvider, RazorViewCompilerProvider>();
services.TryAddSingleton<IViewCompilationMemoryCacheProvider, RazorViewCompilationMemoryCacheProvider>();
// In the default scenario the following services are singleton by virtue of being initialized as part of
// creating the singleton RazorViewEngine instance.

View File

@ -34,9 +34,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
private readonly IFileProvider _fileProvider;
private readonly RazorProjectEngine _projectEngine;
private readonly Action<RoslynCompilationContext> _compilationCallback;
private readonly IMemoryCache _cache;
private readonly ILogger _logger;
private readonly CSharpCompiler _csharpCompiler;
private readonly IMemoryCache _cache;
public RazorViewCompiler(
IFileProvider fileProvider,
@ -44,6 +44,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
CSharpCompiler csharpCompiler,
Action<RoslynCompilationContext> compilationCallback,
IList<CompiledViewDescriptor> precompiledViews,
IMemoryCache cache,
ILogger logger)
{
if (fileProvider == null)
@ -82,11 +83,12 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
_compilationCallback = compilationCallback;
_logger = logger;
_normalizedPathCache = new ConcurrentDictionary<string, string>(StringComparer.Ordinal);
// This is our L0 cache, and is a durable store. Views migrate into the cache as they are requested
// from either the set of known precompiled views, or by being compiled.
_cache = new MemoryCache(new MemoryCacheOptions());
_cache = cache;
// We need to validate that the all of the precompiled views are unique by path (case-insenstive).
// We do this because there's no good way to canonicalize paths on windows, and it will create

View File

@ -18,6 +18,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
private readonly ApplicationPartManager _applicationPartManager;
private readonly IRazorViewEngineFileProviderAccessor _fileProviderAccessor;
private readonly CSharpCompiler _csharpCompiler;
private readonly IViewCompilationMemoryCacheProvider _compilationMemoryCacheProvider;
private readonly RazorViewEngineOptions _viewEngineOptions;
private readonly ILogger<RazorViewCompiler> _logger;
private readonly Func<IViewCompiler> _createCompiler;
@ -32,12 +33,14 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
IRazorViewEngineFileProviderAccessor fileProviderAccessor,
CSharpCompiler csharpCompiler,
IOptions<RazorViewEngineOptions> viewEngineOptionsAccessor,
IViewCompilationMemoryCacheProvider compilationMemoryCacheProvider,
ILoggerFactory loggerFactory)
{
_applicationPartManager = applicationPartManager;
_razorProjectEngine = razorProjectEngine;
_fileProviderAccessor = fileProviderAccessor;
_csharpCompiler = csharpCompiler;
_compilationMemoryCacheProvider = compilationMemoryCacheProvider;
_viewEngineOptions = viewEngineOptionsAccessor.Value;
_logger = loggerFactory.CreateLogger<RazorViewCompiler>();
@ -74,6 +77,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
_csharpCompiler,
_viewEngineOptions.CompilationCallback,
feature.ViewDescriptors,
_compilationMemoryCacheProvider.CompilationMemoryCache,
_logger);
}
}

View File

@ -4,6 +4,7 @@
using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.Razor.Compilation;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Logging.Abstractions;
@ -39,6 +40,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal
accessor,
new CSharpCompiler(referenceManager, Mock.Of<IHostingEnvironment>()),
options,
new RazorViewCompilationMemoryCacheProvider(),
NullLoggerFactory.Instance);
// Act & Assert

View File

@ -13,6 +13,7 @@ using Microsoft.AspNetCore.Razor.Hosting;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Moq;
@ -875,7 +876,7 @@ this should fail";
Action<RoslynCompilationContext> compilationCallback,
IList<CompiledViewDescriptor> precompiledViews,
Func<string, CompiledViewDescriptor> compile = null) :
base(fileProvider, projectEngine, csharpCompiler, compilationCallback, precompiledViews, NullLogger.Instance)
base(fileProvider, projectEngine, csharpCompiler, compilationCallback, precompiledViews, new MemoryCache(new MemoryCacheOptions()), NullLogger.Instance)
{
Compile = compile;
if (Compile == null)