// 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.Compilation; namespace Microsoft.AspNet.Mvc.Razor { /// /// Represents a that creates instances /// from razor files in the file system. /// public class DefaultRazorPageFactoryProvider : IRazorPageFactoryProvider { /// /// This delegate holds on to an instance of . /// private readonly Func _compileDelegate; private readonly ICompilerCacheProvider _compilerCacheProvider; private ICompilerCache _compilerCache; /// /// Initializes a new instance of . /// /// The . /// The . public DefaultRazorPageFactoryProvider( IRazorCompilationService razorCompilationService, ICompilerCacheProvider compilerCacheProvider) { _compileDelegate = razorCompilationService.Compile; _compilerCacheProvider = compilerCacheProvider; } private ICompilerCache CompilerCache { get { if (_compilerCache == null) { _compilerCache = _compilerCacheProvider.Cache; } return _compilerCache; } } /// public RazorPageFactoryResult CreateFactory(string relativePath) { if (relativePath == null) { throw new ArgumentNullException(nameof(relativePath)); } if (relativePath.StartsWith("~/", StringComparison.Ordinal)) { // For tilde slash paths, drop the leading ~ to make it work with the underlying IFileProvider. relativePath = relativePath.Substring(1); } var result = CompilerCache.GetOrAdd(relativePath, _compileDelegate); if (result.Success) { var pageFactory = GetPageFactory(result.CompilationResult.CompiledType, relativePath); return new RazorPageFactoryResult(pageFactory, result.ExpirationTokens); } else { return new RazorPageFactoryResult(result.ExpirationTokens); } } /// /// Creates a factory for . /// /// The to produce an instance of /// from. /// The application relative path of the page. /// A factory for . protected virtual Func GetPageFactory(Type compiledType, string relativePath) { return () => { var page = (IRazorPage)Activator.CreateInstance(compiledType); page.Path = relativePath; return page; }; } } }