Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

Commit

Permalink
Register DependencyContextRazorViewEngineOptionsSetup after RazorView…
Browse files Browse the repository at this point in the history
…EngineOptionsSetup

Fixes #4902
  • Loading branch information
pranavkm committed Jul 8, 2016
1 parent 7430efa commit 98e9a01
Show file tree
Hide file tree
Showing 6 changed files with 367 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -127,18 +127,20 @@ public static IMvcCoreBuilder InitializeTagHelper<TTagHelper>(
// Internal for testing.
internal static void AddRazorViewEngineServices(IServiceCollection services)
{
services.TryAddEnumerable(
ServiceDescriptor.Transient<
IConfigureOptions<RazorViewEngineOptions>,
DependencyContextRazorViewEngineOptionsSetup>());

// This caches compilation related details that are valid across the lifetime of the application.
services.TryAddSingleton<ICompilationService, DefaultRoslynCompilationService>();

services.TryAddEnumerable(
ServiceDescriptor.Transient<IConfigureOptions<MvcViewOptions>, MvcRazorMvcViewOptionsSetup>());

// DependencyContextRazorViewEngineOptionsSetup needs to run after RazorViewEngineOptionsSetup.
// The ordering of the following two lines is important to ensure this behavior.
services.TryAddEnumerable(
ServiceDescriptor.Transient<IConfigureOptions<RazorViewEngineOptions>, RazorViewEngineOptionsSetup>());
services.TryAddEnumerable(
ServiceDescriptor.Transient<
IConfigureOptions<RazorViewEngineOptions>,
DependencyContextRazorViewEngineOptionsSetup>());

services.TryAddSingleton<
IRazorViewEngineFileProviderAccessor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,54 @@
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.Extensions.DependencyModel;
using Microsoft.Extensions.Options;
using DependencyContextOptions = Microsoft.Extensions.DependencyModel.CompilationOptions;

namespace Microsoft.AspNetCore.Mvc.Razor.Internal
{
/// <summary>
/// Sets up compilation and parse option default options for <see cref="RazorViewEngineOptions"/> using
/// <see cref="DependencyContext"/>
/// </summary>
public class DependencyContextRazorViewEngineOptionsSetup : ConfigureOptions<RazorViewEngineOptions>
public class DependencyContextRazorViewEngineOptionsSetup : IConfigureOptions<RazorViewEngineOptions>
{
private readonly IHostingEnvironment _hostingEnvironment;

/// <summary>
/// Initializes a new instance of <see cref="DependencyContextRazorViewEngineOptionsSetup"/>.
/// </summary>
public DependencyContextRazorViewEngineOptionsSetup(IHostingEnvironment hostingEnvironment)
: base(options => ConfigureRazor(options, hostingEnvironment))
{
_hostingEnvironment = hostingEnvironment;
}

private static void ConfigureRazor(RazorViewEngineOptions options, IHostingEnvironment hostingEnvironment)
/// <inheritdoc />
public void Configure(RazorViewEngineOptions options)
{
var applicationAssembly = Assembly.Load(new AssemblyName(hostingEnvironment.ApplicationName));
var dependencyContext = DependencyContext.Load(applicationAssembly);
var compilationOptions = dependencyContext?.CompilationOptions ?? Extensions.DependencyModel.CompilationOptions.Default;
var compilationOptions = GetCompilationOptions();

SetParseOptions(options, compilationOptions);
SetCompilationOptions(options, compilationOptions);
}

private static void SetCompilationOptions(RazorViewEngineOptions options, Extensions.DependencyModel.CompilationOptions compilationOptions)
// Internal for unit testing.
protected internal virtual DependencyContextOptions GetCompilationOptions()
{
if (!string.IsNullOrEmpty(_hostingEnvironment.ApplicationName))

This comment has been minimized.

Copy link
@davidfowl

davidfowl Jul 8, 2016

Member

When is this null?

This comment has been minimized.

Copy link
@pranavkm

pranavkm Jul 8, 2016

Author Contributor

In cases like this - aspnet/Razor#793 (comment) - where it's not being run as part of an application.

{
var applicationAssembly = Assembly.Load(new AssemblyName(_hostingEnvironment.ApplicationName));
var dependencyContext = DependencyContext.Load(applicationAssembly);
if (dependencyContext?.CompilationOptions != null)
{
return dependencyContext.CompilationOptions;
}
}

return DependencyContextOptions.Default;
}

private static void SetCompilationOptions(
RazorViewEngineOptions options,
DependencyContextOptions compilationOptions)
{
var roslynOptions = options.CompilationOptions;

Expand All @@ -57,17 +77,17 @@ private static void SetCompilationOptions(RazorViewEngineOptions options, Extens

if (compilationOptions.Optimize.HasValue)
{
var optimizationLevel = compilationOptions.Optimize.Value
? OptimizationLevel.Debug
: OptimizationLevel.Release;
var optimizationLevel = compilationOptions.Optimize.Value ?
OptimizationLevel.Release :
OptimizationLevel.Debug;
roslynOptions = roslynOptions.WithOptimizationLevel(optimizationLevel);
}

if (compilationOptions.WarningsAsErrors.HasValue)
{
var reportDiagnostic = compilationOptions.WarningsAsErrors.Value
? ReportDiagnostic.Error
: ReportDiagnostic.Default;
var reportDiagnostic = compilationOptions.WarningsAsErrors.Value ?
ReportDiagnostic.Error :
ReportDiagnostic.Default;
roslynOptions = roslynOptions.WithGeneralDiagnosticOption(reportDiagnostic);
}

Expand All @@ -76,7 +96,7 @@ private static void SetCompilationOptions(RazorViewEngineOptions options, Extens

private static void SetParseOptions(
RazorViewEngineOptions options,
Extensions.DependencyModel.CompilationOptions compilationOptions)
DependencyContextOptions compilationOptions)
{
var parseOptions = options.ParseOptions;
parseOptions = parseOptions.WithPreprocessorSymbols(
Expand Down
40 changes: 20 additions & 20 deletions src/Microsoft.AspNetCore.Mvc.Razor/RazorViewEngineOptionsSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,51 +12,51 @@ namespace Microsoft.AspNetCore.Mvc
/// <summary>
/// Sets up default options for <see cref="RazorViewEngineOptions"/>.
/// </summary>
public class RazorViewEngineOptionsSetup : ConfigureOptions<RazorViewEngineOptions>
public class RazorViewEngineOptionsSetup : IConfigureOptions<RazorViewEngineOptions>
{
private readonly IHostingEnvironment _hostingEnvironment;

/// <summary>
/// Initializes a new instance of <see cref="RazorViewEngineOptions"/>.
/// </summary>
/// <param name="hostingEnvironment"><see cref="IHostingEnvironment"/> for the application.</param>
public RazorViewEngineOptionsSetup(
IHostingEnvironment hostingEnvironment)
: base(options => ConfigureRazor(options, hostingEnvironment))
public RazorViewEngineOptionsSetup(IHostingEnvironment hostingEnvironment)
{
_hostingEnvironment = hostingEnvironment;
}

private static void ConfigureRazor(
RazorViewEngineOptions razorOptions,
IHostingEnvironment hostingEnvironment)
/// <inheritdoc />
public void Configure(RazorViewEngineOptions options)
{
if (hostingEnvironment.ContentRootFileProvider != null)
if (_hostingEnvironment.ContentRootFileProvider != null)
{
razorOptions.FileProviders.Add(hostingEnvironment.ContentRootFileProvider);
options.FileProviders.Add(_hostingEnvironment.ContentRootFileProvider);
}

var compilationOptions = razorOptions.CompilationOptions;
var compilationOptions = options.CompilationOptions;
string configurationSymbol;

if (hostingEnvironment.IsDevelopment())
if (_hostingEnvironment.IsDevelopment())
{
configurationSymbol = "DEBUG";
razorOptions.CompilationOptions = compilationOptions.WithOptimizationLevel(OptimizationLevel.Debug);
options.CompilationOptions = compilationOptions.WithOptimizationLevel(OptimizationLevel.Debug);
}
else
{
configurationSymbol = "RELEASE";
razorOptions.CompilationOptions = compilationOptions.WithOptimizationLevel(OptimizationLevel.Release);
options.CompilationOptions = compilationOptions.WithOptimizationLevel(OptimizationLevel.Release);
}

var parseOptions = razorOptions.ParseOptions;
razorOptions.ParseOptions = parseOptions.WithPreprocessorSymbols(
var parseOptions = options.ParseOptions;
options.ParseOptions = parseOptions.WithPreprocessorSymbols(
parseOptions.PreprocessorSymbolNames.Concat(new[] { configurationSymbol }));

razorOptions.ViewLocationFormats.Add("/Views/{1}/{0}" + RazorViewEngine.ViewExtension);
razorOptions.ViewLocationFormats.Add("/Views/Shared/{0}" + RazorViewEngine.ViewExtension);
options.ViewLocationFormats.Add("/Views/{1}/{0}" + RazorViewEngine.ViewExtension);
options.ViewLocationFormats.Add("/Views/Shared/{0}" + RazorViewEngine.ViewExtension);

razorOptions.AreaViewLocationFormats.Add("/Areas/{2}/Views/{1}/{0}" + RazorViewEngine.ViewExtension);
razorOptions.AreaViewLocationFormats.Add("/Areas/{2}/Views/Shared/{0}" + RazorViewEngine.ViewExtension);
razorOptions.AreaViewLocationFormats.Add("/Views/Shared/{0}" + RazorViewEngine.ViewExtension);
options.AreaViewLocationFormats.Add("/Areas/{2}/Views/{1}/{0}" + RazorViewEngine.ViewExtension);
options.AreaViewLocationFormats.Add("/Areas/{2}/Views/Shared/{0}" + RazorViewEngine.ViewExtension);
options.AreaViewLocationFormats.Add("/Views/Shared/{0}" + RazorViewEngine.ViewExtension);
}
}
}
Loading

0 comments on commit 98e9a01

Please sign in to comment.