diff --git a/src/Microsoft.AspNet.Mvc.Razor/DependencyInjection/MvcRazorMvcCoreBuilderExtensions.cs b/src/Microsoft.AspNet.Mvc.Razor/DependencyInjection/MvcRazorMvcCoreBuilderExtensions.cs index bd7dfe694d..d2fca5828d 100644 --- a/src/Microsoft.AspNet.Mvc.Razor/DependencyInjection/MvcRazorMvcCoreBuilderExtensions.cs +++ b/src/Microsoft.AspNet.Mvc.Razor/DependencyInjection/MvcRazorMvcCoreBuilderExtensions.cs @@ -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(); - // Caches compilation artifacts across the lifetime of the application. services.TryAddSingleton(); - // 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(); - // 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(); - - // The ViewStartProvider needs to be able to consume scoped instances of IRazorPageFactory - services.TryAddScoped(); + // In the default scenario the following services are singleton by virtue of being initialized as part of + // creating the singleton RazorViewEngine instance. services.TryAddTransient(); - services.TryAddSingleton(); + services.TryAddTransient(); + services.TryAddTransient(); + services.TryAddTransient(); + services.TryAddTransient(); - // Virtual path view factory needs to stay scoped so views can get get scoped services. - services.TryAddScoped(); + // This caches Razor page activation details that are valid for the lifetime of the application. + services.TryAddSingleton(); // Only want one ITagHelperActivator so it can cache Type activation information. Types won't conflict. services.TryAddSingleton(); diff --git a/src/Microsoft.AspNet.Mvc.Razor/VirtualPathRazorPageFactory.cs b/src/Microsoft.AspNet.Mvc.Razor/VirtualPathRazorPageFactory.cs index 93cc6e578b..4d29760242 100644 --- a/src/Microsoft.AspNet.Mvc.Razor/VirtualPathRazorPageFactory.cs +++ b/src/Microsoft.AspNet.Mvc.Razor/VirtualPathRazorPageFactory.cs @@ -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 /// public class VirtualPathRazorPageFactory : IRazorPageFactory { - private readonly IServiceProvider _serviceProvider; + /// + /// This delegate holds on to an instance of . + /// + private readonly Func _compileDelegate; private readonly ICompilerCacheProvider _compilerCacheProvider; - private IRazorCompilationService _razorcompilationService; private ICompilerCache _compilerCache; /// /// Initializes a new instance of . /// - /// The request specific . + /// The . /// The . 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(); - } - - 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) { diff --git a/test/Microsoft.AspNet.Mvc.Test/MvcOptionsSetupTest.cs b/test/Microsoft.AspNet.Mvc.Test/MvcOptionsSetupTest.cs index eeefe46b69..992f67510e 100644 --- a/test/Microsoft.AspNet.Mvc.Test/MvcOptionsSetupTest.cs +++ b/test/Microsoft.AspNet.Mvc.Test/MvcOptionsSetupTest.cs @@ -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()); + serviceCollection.AddInstance(Mock.Of()); + serviceCollection.AddInstance(Mock.Of()); serviceCollection.AddInstance(Mock.Of()); var applicationEnvironment = new Mock();