Add MVC support for RazorProjectEngine.
- Make `RazorProjectEngine` call paths for all feature registrations. - Add `DefaultMvcImportFeature` for latest and 1.X MVC. - Ported `AddTargetExtension` and `AddDirective` to `RazorProjectEngineBuilderExtensions`. - Added tests and a test file system project type. - Moved obsolete `IRazorEngineBuilder` methods to the bottom of each file. Will actually obsolete the methods once `RazorProjectEngine` is working end-to-end. #1828
This commit is contained in:
parent
bc6d726c36
commit
771a7e35a4
|
|
@ -0,0 +1,84 @@
|
|||
// 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 System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
|
||||
{
|
||||
internal class DefaultMvcImportFeature : RazorProjectEngineFeatureBase, IRazorImportFeature
|
||||
{
|
||||
private const string ImportsFileName = "_ViewImports.cshtml";
|
||||
|
||||
public IReadOnlyList<RazorSourceDocument> GetImports(string sourceFilePath)
|
||||
{
|
||||
if (string.IsNullOrEmpty(sourceFilePath))
|
||||
{
|
||||
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpy, nameof(sourceFilePath));
|
||||
}
|
||||
|
||||
var imports = new List<RazorSourceDocument>();
|
||||
AddDefaultDirectivesImport(imports);
|
||||
|
||||
// We add hierarchical imports second so any default directive imports can be overridden.
|
||||
AddHierarchicalImports(sourceFilePath, imports);
|
||||
|
||||
return imports;
|
||||
}
|
||||
|
||||
// Internal for testing
|
||||
internal static void AddDefaultDirectivesImport(List<RazorSourceDocument> imports)
|
||||
{
|
||||
using (var stream = new MemoryStream())
|
||||
using (var writer = new StreamWriter(stream, Encoding.UTF8))
|
||||
{
|
||||
writer.WriteLine("@using System");
|
||||
writer.WriteLine("@using System.Collections.Generic");
|
||||
writer.WriteLine("@using System.Linq");
|
||||
writer.WriteLine("@using System.Threading.Tasks");
|
||||
writer.WriteLine("@using Microsoft.AspNetCore.Mvc");
|
||||
writer.WriteLine("@using Microsoft.AspNetCore.Mvc.Rendering");
|
||||
writer.WriteLine("@using Microsoft.AspNetCore.Mvc.ViewFeatures");
|
||||
writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel> Html");
|
||||
writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json");
|
||||
writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component");
|
||||
writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.IUrlHelper Url");
|
||||
writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider");
|
||||
writer.WriteLine("@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor");
|
||||
writer.Flush();
|
||||
|
||||
stream.Position = 0;
|
||||
var defaultMvcImports = RazorSourceDocument.ReadFrom(stream, fileName: null, encoding: Encoding.UTF8);
|
||||
imports.Add(defaultMvcImports);
|
||||
}
|
||||
}
|
||||
|
||||
// Internal for testing
|
||||
internal void AddHierarchicalImports(string sourceFilePath, List<RazorSourceDocument> imports)
|
||||
{
|
||||
// We want items in descending order. FindHierarchicalItems returns items in ascending order.
|
||||
var importProjectItems = ProjectEngine.FileSystem.FindHierarchicalItems(sourceFilePath, ImportsFileName).Reverse();
|
||||
foreach (var importProjectItem in importProjectItems)
|
||||
{
|
||||
RazorSourceDocument importSourceDocument;
|
||||
|
||||
if (importProjectItem.Exists)
|
||||
{
|
||||
importSourceDocument = RazorSourceDocument.ReadFrom(importProjectItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
// File doesn't exist on disk so just add a marker source document as an identifier for "there could be something here".
|
||||
var sourceDocumentProperties = new RazorSourceDocumentProperties(importProjectItem.FilePath, importProjectItem.RelativePhysicalPath);
|
||||
importSourceDocument = RazorSourceDocument.Create(string.Empty, sourceDocumentProperties);
|
||||
}
|
||||
|
||||
imports.Add(importSourceDocument);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -24,8 +24,13 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
|
|||
builder.Description = Resources.InjectDirective_Description;
|
||||
});
|
||||
|
||||
public static IRazorEngineBuilder Register(IRazorEngineBuilder builder)
|
||||
public static RazorProjectEngineBuilder Register(RazorProjectEngineBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.AddDirective(Directive);
|
||||
builder.Features.Add(new Pass());
|
||||
builder.AddTargetExtension(new InjectTargetExtension());
|
||||
|
|
@ -99,5 +104,20 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Obsolete
|
||||
public static IRazorEngineBuilder Register(IRazorEngineBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.AddDirective(Directive);
|
||||
builder.Features.Add(new Pass());
|
||||
builder.AddTargetExtension(new InjectTargetExtension());
|
||||
return builder;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,8 +21,13 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
|
|||
builder.Description = Resources.ModelDirective_Description;
|
||||
});
|
||||
|
||||
public static IRazorEngineBuilder Register(IRazorEngineBuilder builder)
|
||||
public static RazorProjectEngineBuilder Register(RazorProjectEngineBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.AddDirective(Directive);
|
||||
builder.Features.Add(new Pass(builder.DesignTime));
|
||||
return builder;
|
||||
|
|
@ -128,5 +133,19 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Obsolete
|
||||
public static IRazorEngineBuilder Register(IRazorEngineBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.AddDirective(Directive);
|
||||
builder.Features.Add(new Pass(builder.DesignTime));
|
||||
return builder;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,8 +9,68 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
|
|||
{
|
||||
public static class RazorExtensions
|
||||
{
|
||||
public static void Register(RazorProjectEngineBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
EnsureDesignTime(builder);
|
||||
|
||||
InjectDirective.Register(builder);
|
||||
ModelDirective.Register(builder);
|
||||
|
||||
FunctionsDirective.Register(builder);
|
||||
InheritsDirective.Register(builder);
|
||||
|
||||
// Register section directive with the 1.x compatible target extension.
|
||||
builder.AddDirective(SectionDirective.Directive);
|
||||
builder.Features.Add(new SectionDirectivePass());
|
||||
builder.AddTargetExtension(new LegacySectionTargetExtension());
|
||||
|
||||
builder.AddTargetExtension(new TemplateTargetExtension()
|
||||
{
|
||||
TemplateTypeName = "global::Microsoft.AspNetCore.Mvc.Razor.HelperResult",
|
||||
});
|
||||
|
||||
builder.Features.Add(new ModelExpressionPass());
|
||||
builder.Features.Add(new MvcViewDocumentClassifierPass());
|
||||
|
||||
builder.SetImportFeature(new DefaultMvcImportFeature());
|
||||
}
|
||||
|
||||
public static void RegisterViewComponentTagHelpers(RazorProjectEngineBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
EnsureDesignTime(builder);
|
||||
|
||||
builder.Features.Add(new ViewComponentTagHelperPass());
|
||||
builder.AddTargetExtension(new ViewComponentTagHelperTargetExtension());
|
||||
}
|
||||
|
||||
private static void EnsureDesignTime(RazorProjectEngineBuilder builder)
|
||||
{
|
||||
if (builder.DesignTime)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
throw new NotSupportedException(Resources.RuntimeCodeGenerationNotSupported);
|
||||
}
|
||||
|
||||
#region Obsolete
|
||||
public static void Register(IRazorEngineBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
EnsureDesignTime(builder);
|
||||
|
||||
InjectDirective.Register(builder);
|
||||
|
|
@ -35,6 +95,11 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
|
|||
|
||||
public static void RegisterViewComponentTagHelpers(IRazorEngineBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
EnsureDesignTime(builder);
|
||||
|
||||
builder.Features.Add(new ViewComponentTagHelperPass());
|
||||
|
|
@ -50,5 +115,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
|
|||
|
||||
throw new NotSupportedException(Resources.RuntimeCodeGenerationNotSupported);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
// 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 System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
||||
{
|
||||
internal class DefaultMvcImportFeature : RazorProjectEngineFeatureBase, IRazorImportFeature
|
||||
{
|
||||
private const string ImportsFileName = "_ViewImports.cshtml";
|
||||
|
||||
public IReadOnlyList<RazorSourceDocument> GetImports(string sourceFilePath)
|
||||
{
|
||||
if (string.IsNullOrEmpty(sourceFilePath))
|
||||
{
|
||||
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpy, nameof(sourceFilePath));
|
||||
}
|
||||
|
||||
var imports = new List<RazorSourceDocument>();
|
||||
AddDefaultDirectivesImport(imports);
|
||||
|
||||
// We add hierarchical imports second so any default directive imports can be overridden.
|
||||
AddHierarchicalImports(sourceFilePath, imports);
|
||||
|
||||
return imports;
|
||||
}
|
||||
|
||||
// Internal for testing
|
||||
internal static void AddDefaultDirectivesImport(List<RazorSourceDocument> imports)
|
||||
{
|
||||
using (var stream = new MemoryStream())
|
||||
using (var writer = new StreamWriter(stream, Encoding.UTF8))
|
||||
{
|
||||
writer.WriteLine("@using System");
|
||||
writer.WriteLine("@using System.Collections.Generic");
|
||||
writer.WriteLine("@using System.Linq");
|
||||
writer.WriteLine("@using System.Threading.Tasks");
|
||||
writer.WriteLine("@using Microsoft.AspNetCore.Mvc");
|
||||
writer.WriteLine("@using Microsoft.AspNetCore.Mvc.Rendering");
|
||||
writer.WriteLine("@using Microsoft.AspNetCore.Mvc.ViewFeatures");
|
||||
writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<TModel> Html");
|
||||
writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.Rendering.IJsonHelper Json");
|
||||
writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.IViewComponentHelper Component");
|
||||
writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.IUrlHelper Url");
|
||||
writer.WriteLine("@inject global::Microsoft.AspNetCore.Mvc.ViewFeatures.IModelExpressionProvider ModelExpressionProvider");
|
||||
writer.WriteLine("@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.UrlResolutionTagHelper, Microsoft.AspNetCore.Mvc.Razor");
|
||||
writer.WriteLine("@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.HeadTagHelper, Microsoft.AspNetCore.Mvc.Razor");
|
||||
writer.WriteLine("@addTagHelper Microsoft.AspNetCore.Mvc.Razor.TagHelpers.BodyTagHelper, Microsoft.AspNetCore.Mvc.Razor");
|
||||
writer.Flush();
|
||||
|
||||
stream.Position = 0;
|
||||
var defaultMvcImports = RazorSourceDocument.ReadFrom(stream, fileName: null, encoding: Encoding.UTF8);
|
||||
imports.Add(defaultMvcImports);
|
||||
}
|
||||
}
|
||||
|
||||
// Internal for testing
|
||||
internal void AddHierarchicalImports(string sourceFilePath, List<RazorSourceDocument> imports)
|
||||
{
|
||||
// We want items in descending order. FindHierarchicalItems returns items in ascending order.
|
||||
var importProjectItems = ProjectEngine.FileSystem.FindHierarchicalItems(sourceFilePath, ImportsFileName).Reverse();
|
||||
foreach (var importProjectItem in importProjectItems)
|
||||
{
|
||||
RazorSourceDocument importSourceDocument;
|
||||
|
||||
if (importProjectItem.Exists)
|
||||
{
|
||||
importSourceDocument = RazorSourceDocument.ReadFrom(importProjectItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
// File doesn't exist on disk so just add a marker source document as an identifier for "there could be something here".
|
||||
var sourceDocumentProperties = new RazorSourceDocumentProperties(importProjectItem.FilePath, importProjectItem.RelativePhysicalPath);
|
||||
importSourceDocument = RazorSourceDocument.Create(string.Empty, sourceDocumentProperties);
|
||||
}
|
||||
|
||||
imports.Add(importSourceDocument);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -24,8 +24,13 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
builder.Description = Resources.InjectDirective_Description;
|
||||
});
|
||||
|
||||
public static IRazorEngineBuilder Register(IRazorEngineBuilder builder)
|
||||
public static RazorProjectEngineBuilder Register(RazorProjectEngineBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.AddDirective(Directive);
|
||||
builder.Features.Add(new Pass());
|
||||
builder.AddTargetExtension(new InjectTargetExtension());
|
||||
|
|
@ -99,5 +104,20 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Obsolete
|
||||
public static IRazorEngineBuilder Register(IRazorEngineBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.AddDirective(Directive);
|
||||
builder.Features.Add(new Pass());
|
||||
builder.AddTargetExtension(new InjectTargetExtension());
|
||||
return builder;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,8 +21,13 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
builder.Description = Resources.ModelDirective_Description;
|
||||
});
|
||||
|
||||
public static IRazorEngineBuilder Register(IRazorEngineBuilder builder)
|
||||
public static RazorProjectEngineBuilder Register(RazorProjectEngineBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.AddDirective(Directive);
|
||||
builder.Features.Add(new Pass(builder.DesignTime));
|
||||
return builder;
|
||||
|
|
@ -135,5 +140,19 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Obsolete
|
||||
public static IRazorEngineBuilder Register(IRazorEngineBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.AddDirective(Directive);
|
||||
builder.Features.Add(new Pass(builder.DesignTime));
|
||||
return builder;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
builder.Description = Resources.NamespaceDirective_Description;
|
||||
});
|
||||
|
||||
public static void Register(IRazorEngineBuilder builder)
|
||||
public static void Register(RazorProjectEngineBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
|
|
@ -186,5 +186,18 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
base.VisitDirective(node);
|
||||
}
|
||||
}
|
||||
|
||||
#region Obsolete
|
||||
public static void Register(IRazorEngineBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
builder.AddDirective(Directive);
|
||||
builder.Features.Add(new Pass());
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,8 +32,13 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
|
||||
public IntermediateNode DirectiveNode { get; }
|
||||
|
||||
public static IRazorEngineBuilder Register(IRazorEngineBuilder builder)
|
||||
public static RazorProjectEngineBuilder Register(RazorProjectEngineBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.AddDirective(Directive);
|
||||
return builder;
|
||||
}
|
||||
|
|
@ -98,5 +103,18 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Obsolete
|
||||
public static IRazorEngineBuilder Register(IRazorEngineBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.AddDirective(Directive);
|
||||
return builder;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// 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.AspNetCore.Razor.Language;
|
||||
using Microsoft.AspNetCore.Razor.Language.Extensions;
|
||||
|
||||
|
|
@ -8,8 +9,51 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
{
|
||||
public static class RazorExtensions
|
||||
{
|
||||
public static void Register(RazorProjectEngineBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
InjectDirective.Register(builder);
|
||||
ModelDirective.Register(builder);
|
||||
NamespaceDirective.Register(builder);
|
||||
PageDirective.Register(builder);
|
||||
|
||||
FunctionsDirective.Register(builder);
|
||||
InheritsDirective.Register(builder);
|
||||
SectionDirective.Register(builder);
|
||||
|
||||
builder.AddTargetExtension(new ViewComponentTagHelperTargetExtension());
|
||||
builder.AddTargetExtension(new TemplateTargetExtension()
|
||||
{
|
||||
TemplateTypeName = "global::Microsoft.AspNetCore.Mvc.Razor.HelperResult",
|
||||
});
|
||||
|
||||
builder.Features.Add(new ModelExpressionPass());
|
||||
builder.Features.Add(new PagesPropertyInjectionPass());
|
||||
builder.Features.Add(new ViewComponentTagHelperPass());
|
||||
builder.Features.Add(new RazorPageDocumentClassifierPass());
|
||||
builder.Features.Add(new MvcViewDocumentClassifierPass());
|
||||
|
||||
if (!builder.DesignTime)
|
||||
{
|
||||
builder.Features.Add(new AssemblyAttributeInjectionPass());
|
||||
builder.Features.Add(new InstrumentationPass());
|
||||
}
|
||||
|
||||
builder.SetImportFeature(new DefaultMvcImportFeature());
|
||||
}
|
||||
|
||||
#region Obsolete
|
||||
public static void Register(IRazorEngineBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
InjectDirective.Register(builder);
|
||||
ModelDirective.Register(builder);
|
||||
NamespaceDirective.Register(builder);
|
||||
|
|
@ -37,5 +81,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
|||
builder.Features.Add(new InstrumentationPass());
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,10 +6,8 @@ using System.Collections.Generic;
|
|||
|
||||
namespace Microsoft.AspNetCore.Razor.Language
|
||||
{
|
||||
internal class DefaultRazorImportFeature : IRazorImportFeature
|
||||
internal class DefaultRazorImportFeature : RazorProjectEngineFeatureBase, IRazorImportFeature
|
||||
{
|
||||
public RazorProjectEngine ProjectEngine { get; set; }
|
||||
|
||||
public IReadOnlyList<RazorSourceDocument> GetImports(string sourceFilePath) => Array.Empty<RazorSourceDocument>();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// 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.AspNetCore.Razor.Language.Legacy;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Extensions
|
||||
|
|
@ -15,10 +16,28 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
|
|||
builder.Description = Resources.FunctionsDirective_Description;
|
||||
});
|
||||
|
||||
public static void Register(IRazorEngineBuilder builder)
|
||||
public static void Register(RazorProjectEngineBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.AddDirective(Directive);
|
||||
builder.Features.Add(new FunctionsDirectivePass());
|
||||
}
|
||||
|
||||
#region Obsolete
|
||||
public static void Register(IRazorEngineBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.AddDirective(Directive);
|
||||
builder.Features.Add(new FunctionsDirectivePass());
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// 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.AspNetCore.Razor.Language.Legacy;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Extensions
|
||||
|
|
@ -17,10 +18,28 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
|
|||
builder.Description = Resources.InheritsDirective_Description;
|
||||
});
|
||||
|
||||
public static void Register(IRazorEngineBuilder builder)
|
||||
public static void Register(RazorProjectEngineBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.AddDirective(Directive);
|
||||
builder.Features.Add(new InheritsDirectivePass());
|
||||
}
|
||||
|
||||
#region Obsolete
|
||||
public static void Register(IRazorEngineBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.AddDirective(Directive);
|
||||
builder.Features.Add(new InheritsDirectivePass());
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// 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.AspNetCore.Razor.Language.Legacy;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language.Extensions
|
||||
|
|
@ -16,11 +17,30 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
|
|||
builder.Description = Resources.SectionDirective_Description;
|
||||
});
|
||||
|
||||
public static void Register(IRazorEngineBuilder builder)
|
||||
public static void Register(RazorProjectEngineBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.AddDirective(Directive);
|
||||
builder.Features.Add(new SectionDirectivePass());
|
||||
builder.AddTargetExtension(new SectionTargetExtension());
|
||||
}
|
||||
|
||||
#region Obsolete
|
||||
public static void Register(IRazorEngineBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
builder.AddDirective(Directive);
|
||||
builder.Features.Add(new SectionDirectivePass());
|
||||
builder.AddTargetExtension(new SectionTargetExtension());
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Razor.Language.CodeGeneration;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language
|
||||
{
|
||||
|
|
@ -29,5 +30,77 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
|
||||
builder.Features.Add(feature);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified <see cref="ICodeTargetExtension"/>.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="RazorProjectEngineBuilder"/>.</param>
|
||||
/// <param name="extension">The <see cref="ICodeTargetExtension"/> to add.</param>
|
||||
/// <returns>The <see cref="RazorProjectEngineBuilder"/>.</returns>
|
||||
public static RazorProjectEngineBuilder AddTargetExtension(this RazorProjectEngineBuilder builder, ICodeTargetExtension extension)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
if (extension == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(extension));
|
||||
}
|
||||
|
||||
var targetExtensionFeature = GetTargetExtensionFeature(builder);
|
||||
targetExtensionFeature.TargetExtensions.Add(extension);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the specified <see cref="DirectiveDescriptor"/>.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="RazorProjectEngineBuilder"/>.</param>
|
||||
/// <param name="directive">The <see cref="DirectiveDescriptor"/> to add.</param>
|
||||
/// <returns>The <see cref="RazorProjectEngineBuilder"/>.</returns>
|
||||
public static RazorProjectEngineBuilder AddDirective(this RazorProjectEngineBuilder builder, DirectiveDescriptor directive)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
if (directive == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(directive));
|
||||
}
|
||||
|
||||
var directiveFeature = GetDirectiveFeature(builder);
|
||||
directiveFeature.Directives.Add(directive);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
private static IRazorDirectiveFeature GetDirectiveFeature(RazorProjectEngineBuilder builder)
|
||||
{
|
||||
var directiveFeature = builder.Features.OfType<IRazorDirectiveFeature>().FirstOrDefault();
|
||||
if (directiveFeature == null)
|
||||
{
|
||||
directiveFeature = new DefaultRazorDirectiveFeature();
|
||||
builder.Features.Add(directiveFeature);
|
||||
}
|
||||
|
||||
return directiveFeature;
|
||||
}
|
||||
|
||||
private static IRazorTargetExtensionFeature GetTargetExtensionFeature(RazorProjectEngineBuilder builder)
|
||||
{
|
||||
var targetExtensionFeature = builder.Features.OfType<IRazorTargetExtensionFeature>().FirstOrDefault();
|
||||
if (targetExtensionFeature == null)
|
||||
{
|
||||
targetExtensionFeature = new DefaultRazorTargetExtensionFeature();
|
||||
builder.Features.Add(targetExtensionFeature);
|
||||
}
|
||||
|
||||
return targetExtensionFeature;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
// 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;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language
|
||||
{
|
||||
public abstract class RazorProjectEngineFeatureBase : IRazorProjectEngineFeature
|
||||
{
|
||||
private RazorProjectEngine _projectEngine;
|
||||
|
||||
public RazorProjectEngine ProjectEngine
|
||||
{
|
||||
get => _projectEngine;
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(value));
|
||||
}
|
||||
|
||||
_projectEngine = value;
|
||||
OnInitialized();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnInitialized()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
// 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.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions
|
||||
{
|
||||
public class DefaultMvcImportFeatureTest
|
||||
{
|
||||
[Fact]
|
||||
public void AddDefaultDirectivesImport_AddsSingleDynamicImport()
|
||||
{
|
||||
// Arrange
|
||||
var imports = new List<RazorSourceDocument>();
|
||||
|
||||
// Act
|
||||
DefaultMvcImportFeature.AddDefaultDirectivesImport(imports);
|
||||
|
||||
// Assert
|
||||
var import = Assert.Single(imports);
|
||||
Assert.Null(import.FilePath);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddHierarchicalImports_AddsViewImportSourceDocumentsOnDisk()
|
||||
{
|
||||
// Arrange
|
||||
var imports = new List<RazorSourceDocument>();
|
||||
var testFileSystem = new TestRazorProjectFileSystem(new[]
|
||||
{
|
||||
new TestRazorProjectItem("/Index.cshtml"),
|
||||
new TestRazorProjectItem("/_ViewImports.cshtml"),
|
||||
new TestRazorProjectItem("/Contact/_ViewImports.cshtml"),
|
||||
new TestRazorProjectItem("/Contact/Index.cshtml"),
|
||||
});
|
||||
var mvcImportFeature = new DefaultMvcImportFeature()
|
||||
{
|
||||
ProjectEngine = Mock.Of<RazorProjectEngine>(projectEngine => projectEngine.FileSystem == testFileSystem)
|
||||
};
|
||||
|
||||
// Act
|
||||
mvcImportFeature.AddHierarchicalImports("/Contact/Index.cshtml", imports);
|
||||
|
||||
// Assert
|
||||
Assert.Collection(imports,
|
||||
import => Assert.Equal("/_ViewImports.cshtml", import.FilePath),
|
||||
import => Assert.Equal("/Contact/_ViewImports.cshtml", import.FilePath));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddHierarchicalImports_AddsViewImportSourceDocumentsNotOnDisk()
|
||||
{
|
||||
// Arrange
|
||||
var imports = new List<RazorSourceDocument>();
|
||||
var testFileSystem = new TestRazorProjectFileSystem(new[]
|
||||
{
|
||||
new TestRazorProjectItem("/Pages/Contact/Index.cshtml"),
|
||||
});
|
||||
var mvcImportFeature = new DefaultMvcImportFeature()
|
||||
{
|
||||
ProjectEngine = Mock.Of<RazorProjectEngine>(projectEngine => projectEngine.FileSystem == testFileSystem)
|
||||
};
|
||||
|
||||
// Act
|
||||
mvcImportFeature.AddHierarchicalImports("/Pages/Contact/Index.cshtml", imports);
|
||||
|
||||
// Assert
|
||||
Assert.Collection(imports,
|
||||
import => Assert.Equal("/_ViewImports.cshtml", import.FilePath),
|
||||
import => Assert.Equal("/Pages/_ViewImports.cshtml", import.FilePath),
|
||||
import => Assert.Equal("/Pages/Contact/_ViewImports.cshtml", import.FilePath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
// 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.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X
|
||||
{
|
||||
public class DefaultMvcImportFeatureTest
|
||||
{
|
||||
[Fact]
|
||||
public void AddDefaultDirectivesImport_AddsSingleDynamicImport()
|
||||
{
|
||||
// Arrange
|
||||
var imports = new List<RazorSourceDocument>();
|
||||
|
||||
// Act
|
||||
DefaultMvcImportFeature.AddDefaultDirectivesImport(imports);
|
||||
|
||||
// Assert
|
||||
var import = Assert.Single(imports);
|
||||
Assert.Null(import.FilePath);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddHierarchicalImports_AddsViewImportSourceDocumentsOnDisk()
|
||||
{
|
||||
// Arrange
|
||||
var imports = new List<RazorSourceDocument>();
|
||||
var testFileSystem = new TestRazorProjectFileSystem(new[]
|
||||
{
|
||||
new TestRazorProjectItem("/Index.cshtml"),
|
||||
new TestRazorProjectItem("/_ViewImports.cshtml"),
|
||||
new TestRazorProjectItem("/Contact/_ViewImports.cshtml"),
|
||||
new TestRazorProjectItem("/Contact/Index.cshtml"),
|
||||
});
|
||||
var mvcImportFeature = new DefaultMvcImportFeature()
|
||||
{
|
||||
ProjectEngine = Mock.Of<RazorProjectEngine>(projectEngine => projectEngine.FileSystem == testFileSystem)
|
||||
};
|
||||
|
||||
// Act
|
||||
mvcImportFeature.AddHierarchicalImports("/Contact/Index.cshtml", imports);
|
||||
|
||||
// Assert
|
||||
Assert.Collection(imports,
|
||||
import => Assert.Equal("/_ViewImports.cshtml", import.FilePath),
|
||||
import => Assert.Equal("/Contact/_ViewImports.cshtml", import.FilePath));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddHierarchicalImports_AddsViewImportSourceDocumentsNotOnDisk()
|
||||
{
|
||||
// Arrange
|
||||
var imports = new List<RazorSourceDocument>();
|
||||
var testFileSystem = new TestRazorProjectFileSystem(new[]
|
||||
{
|
||||
new TestRazorProjectItem("/Pages/Contact/Index.cshtml"),
|
||||
});
|
||||
var mvcImportFeature = new DefaultMvcImportFeature()
|
||||
{
|
||||
ProjectEngine = Mock.Of<RazorProjectEngine>(projectEngine => projectEngine.FileSystem == testFileSystem)
|
||||
};
|
||||
|
||||
// Act
|
||||
mvcImportFeature.AddHierarchicalImports("/Pages/Contact/Index.cshtml", imports);
|
||||
|
||||
// Assert
|
||||
Assert.Collection(imports,
|
||||
import => Assert.Equal("/_ViewImports.cshtml", import.FilePath),
|
||||
import => Assert.Equal("/Pages/_ViewImports.cshtml", import.FilePath),
|
||||
import => Assert.Equal("/Pages/Contact/_ViewImports.cshtml", import.FilePath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
// 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 Microsoft.AspNetCore.Razor.Language.CodeGeneration;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -26,5 +27,77 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
var feature = Assert.Single(builder.Features);
|
||||
Assert.Same(newFeature, feature);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddTargetExtension_CreatesAndAddsToTargetExtensionFeatureIfItDoesNotExist()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultRazorProjectEngineBuilder(false, Mock.Of<RazorProjectFileSystem>());
|
||||
var expectedExtension = Mock.Of<ICodeTargetExtension>();
|
||||
|
||||
// Act
|
||||
builder.AddTargetExtension(expectedExtension);
|
||||
|
||||
// Assert
|
||||
var feature = Assert.Single(builder.Features);
|
||||
var codeTargetExtensionFeature = Assert.IsAssignableFrom<IRazorTargetExtensionFeature>(feature);
|
||||
var extensions = Assert.Single(codeTargetExtensionFeature.TargetExtensions);
|
||||
Assert.Same(expectedExtension, extensions);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddTargetExtension_UsesExistingFeatureIfExistsAndAddsTo()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultRazorProjectEngineBuilder(false, Mock.Of<RazorProjectFileSystem>());
|
||||
var codeTargetExtensionFeature = new DefaultRazorTargetExtensionFeature();
|
||||
builder.Features.Add(codeTargetExtensionFeature);
|
||||
var expectedExtension = Mock.Of<ICodeTargetExtension>();
|
||||
|
||||
// Act
|
||||
builder.AddTargetExtension(expectedExtension);
|
||||
|
||||
// Assert
|
||||
var feature = Assert.Single(builder.Features);
|
||||
Assert.Same(codeTargetExtensionFeature, feature);
|
||||
var extensions = Assert.Single(codeTargetExtensionFeature.TargetExtensions);
|
||||
Assert.Same(expectedExtension, extensions);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddDirective_CreatesAndAddsToDirectiveFeatureIfItDoesNotExist()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultRazorProjectEngineBuilder(false, Mock.Of<RazorProjectFileSystem>());
|
||||
var expectedDirective = Mock.Of<DirectiveDescriptor>();
|
||||
|
||||
// Act
|
||||
builder.AddDirective(expectedDirective);
|
||||
|
||||
// Assert
|
||||
var feature = Assert.Single(builder.Features);
|
||||
var directiveFeature = Assert.IsAssignableFrom<IRazorDirectiveFeature>(feature);
|
||||
var directive = Assert.Single(directiveFeature.Directives);
|
||||
Assert.Same(expectedDirective, directive);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddDirective_UsesExistingFeatureIfExistsAndAddsTo()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultRazorProjectEngineBuilder(false, Mock.Of<RazorProjectFileSystem>());
|
||||
var directiveFeature = new DefaultRazorDirectiveFeature();
|
||||
builder.Features.Add(directiveFeature);
|
||||
var expecteDirective = Mock.Of<DirectiveDescriptor>();
|
||||
|
||||
// Act
|
||||
builder.AddDirective(expecteDirective);
|
||||
|
||||
// Assert
|
||||
var feature = Assert.Single(builder.Features);
|
||||
Assert.Same(directiveFeature, feature);
|
||||
var directive = Assert.Single(directiveFeature.Directives);
|
||||
Assert.Same(expecteDirective, directive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
// 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 Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language
|
||||
{
|
||||
public class RazorProjectEngineFeatureBaseTest
|
||||
{
|
||||
[Fact]
|
||||
public void ProjectEngineSetter_CallsOnInitialized()
|
||||
{
|
||||
// Arrange
|
||||
var testFeature = new TestFeature();
|
||||
|
||||
// Act
|
||||
testFeature.ProjectEngine = Mock.Of<RazorProjectEngine>();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(1, testFeature.InitializationCount);
|
||||
}
|
||||
|
||||
private class TestFeature : RazorProjectEngineFeatureBase
|
||||
{
|
||||
public int InitializationCount { get; private set; }
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
InitializationCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue