// 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;
};
}
}
}