* Avoid lazyily evaluating IRazorCompilationService in
VirtualPathRazorPageFactory * Cleanup comments on the lifetime of Razor services.
This commit is contained in:
parent
ddc74e5396
commit
c0d4981452
|
|
@ -96,28 +96,22 @@ namespace Microsoft.Framework.DependencyInjection
|
|||
return new DefaultChunkTreeCache(cachedFileProvider.Options.FileProvider);
|
||||
}));
|
||||
|
||||
// The host is designed to be discarded after consumption and is very inexpensive to initialize.
|
||||
services.TryAddTransient<IMvcRazorHost, MvcRazorHost>();
|
||||
|
||||
// Caches compilation artifacts across the lifetime of the application.
|
||||
services.TryAddSingleton<ICompilerCacheProvider, DefaultCompilerCacheProvider>();
|
||||
|
||||
// This caches compilation related details that are valid across the lifetime of the application
|
||||
// and is required to be a singleton.
|
||||
// This caches compilation related details that are valid across the lifetime of the application.
|
||||
services.TryAddSingleton<ICompilationService, RoslynCompilationService>();
|
||||
|
||||
// Both the compiler cache and roslyn compilation service hold on the compilation related
|
||||
// caches. RazorCompilation service is just an adapter service, and it is transient to ensure
|
||||
// the IMvcRazorHost dependency does not maintain state.
|
||||
services.TryAddTransient<IRazorCompilationService, RazorCompilationService>();
|
||||
|
||||
// The ViewStartProvider needs to be able to consume scoped instances of IRazorPageFactory
|
||||
services.TryAddScoped<IViewStartProvider, ViewStartProvider>();
|
||||
// In the default scenario the following services are singleton by virtue of being initialized as part of
|
||||
// creating the singleton RazorViewEngine instance.
|
||||
services.TryAddTransient<IRazorViewFactory, RazorViewFactory>();
|
||||
services.TryAddSingleton<IRazorPageActivator, RazorPageActivator>();
|
||||
services.TryAddTransient<IRazorPageFactory, VirtualPathRazorPageFactory>();
|
||||
services.TryAddTransient<IRazorCompilationService, RazorCompilationService>();
|
||||
services.TryAddTransient<IViewStartProvider, ViewStartProvider>();
|
||||
services.TryAddTransient<IMvcRazorHost, MvcRazorHost>();
|
||||
|
||||
// Virtual path view factory needs to stay scoped so views can get get scoped services.
|
||||
services.TryAddScoped<IRazorPageFactory, VirtualPathRazorPageFactory>();
|
||||
// This caches Razor page activation details that are valid for the lifetime of the application.
|
||||
services.TryAddSingleton<IRazorPageActivator, RazorPageActivator>();
|
||||
|
||||
// Only want one ITagHelperActivator so it can cache Type activation information. Types won't conflict.
|
||||
services.TryAddSingleton<ITagHelperActivator, DefaultTagHelperActivator>();
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
using System;
|
||||
using Microsoft.AspNet.Mvc.Razor.Compilation;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.Internal;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Razor
|
||||
|
|
@ -14,40 +13,26 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
/// </summary>
|
||||
public class VirtualPathRazorPageFactory : IRazorPageFactory
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
/// <remarks>
|
||||
/// This delegate holds on to an instance of <see cref="IRazorCompilationService"/>.
|
||||
/// </remarks>
|
||||
private readonly Func<RelativeFileInfo, CompilationResult> _compileDelegate;
|
||||
private readonly ICompilerCacheProvider _compilerCacheProvider;
|
||||
private IRazorCompilationService _razorcompilationService;
|
||||
private ICompilerCache _compilerCache;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of <see cref="VirtualPathRazorPageFactory"/>.
|
||||
/// </summary>
|
||||
/// <param name="serviceProvider">The request specific <see cref="IServiceProvider"/>.</param>
|
||||
/// <param name="razorCompilationService">The <see cref="IRazorCompilationService"/>.</param>
|
||||
/// <param name="compilerCacheProvider">The <see cref="ICompilerCacheProvider"/>.</param>
|
||||
public VirtualPathRazorPageFactory(
|
||||
IServiceProvider serviceProvider,
|
||||
IRazorCompilationService razorCompilationService,
|
||||
ICompilerCacheProvider compilerCacheProvider)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
_compileDelegate = razorCompilationService.Compile;
|
||||
_compilerCacheProvider = compilerCacheProvider;
|
||||
}
|
||||
|
||||
private IRazorCompilationService RazorCompilationService
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_razorcompilationService == null)
|
||||
{
|
||||
// it is ok to use the cached service provider because both this, and the
|
||||
// resolved service are in a lifetime of Scoped.
|
||||
// We don't want to get it upfront because it will force Roslyn to load.
|
||||
_razorcompilationService = _serviceProvider.GetRequiredService<IRazorCompilationService>();
|
||||
}
|
||||
|
||||
return _razorcompilationService;
|
||||
}
|
||||
}
|
||||
|
||||
private ICompilerCache CompilerCache
|
||||
{
|
||||
get
|
||||
|
|
@ -70,9 +55,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
relativePath = relativePath.Substring(1);
|
||||
}
|
||||
|
||||
var result = CompilerCache.GetOrAdd(
|
||||
relativePath,
|
||||
RazorCompilationService.Compile);
|
||||
var result = CompilerCache.GetOrAdd(relativePath, _compileDelegate);
|
||||
|
||||
if (result == CompilerCacheResult.FileNotFound)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ using Microsoft.AspNet.Mvc.Internal;
|
|||
using Microsoft.AspNet.Mvc.ModelBinding;
|
||||
using Microsoft.AspNet.Mvc.ModelBinding.Validation;
|
||||
using Microsoft.AspNet.Mvc.Razor;
|
||||
using Microsoft.Dnx.Compilation;
|
||||
using Microsoft.Dnx.Runtime;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
|
|
@ -232,6 +233,8 @@ namespace Microsoft.AspNet.Mvc
|
|||
private static void AddDnxServices(IServiceCollection serviceCollection)
|
||||
{
|
||||
serviceCollection.AddInstance(Mock.Of<ILibraryManager>());
|
||||
serviceCollection.AddInstance(Mock.Of<ILibraryExporter>());
|
||||
serviceCollection.AddInstance(Mock.Of<ICompilerOptionsProvider>());
|
||||
serviceCollection.AddInstance(Mock.Of<IAssemblyLoadContextAccessor>());
|
||||
var applicationEnvironment = new Mock<IApplicationEnvironment>();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue