Support _ViewImports.cshtml files hierarchically

This commit is contained in:
Steve Sanderson 2018-02-18 23:57:20 +00:00
parent be1400663b
commit f649de2976
9 changed files with 108 additions and 9 deletions

View File

@ -0,0 +1,35 @@
// 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;
using System.IO;
namespace Microsoft.AspNetCore.Blazor.Build.Core.RazorCompilation
{
internal class BlazorProjectItem : RazorProjectItem
{
private readonly string _projectBasePath;
private readonly string _itemFullPhysicalPath;
private readonly Stream _itemContents;
public BlazorProjectItem(
string projectBasePath,
string itemFullPhysicalPath,
Stream itemFileContents)
{
_projectBasePath = projectBasePath;
_itemFullPhysicalPath = itemFullPhysicalPath;
_itemContents = itemFileContents;
}
public override string BasePath => _projectBasePath;
public override string FilePath => _itemFullPhysicalPath;
public override string PhysicalPath => _itemFullPhysicalPath;
public override bool Exists => true;
public override Stream Read() => _itemContents;
}
}

View File

@ -94,13 +94,14 @@ namespace Microsoft.AspNetCore.Blazor.Build.Core.RazorCompilation
// invocations.
var engine = new BlazorRazorEngine();
var sourceDoc = RazorSourceDocument.ReadFrom(inputFileContents, inputFilePath);
var codeDoc = RazorCodeDocument.Create(sourceDoc);
var blazorTemplateEngine = new BlazorTemplateEngine(
engine.Engine,
RazorProject.Create(inputRootPath));
var codeDoc = blazorTemplateEngine.CreateCodeDocument(
new BlazorProjectItem(inputRootPath, inputFilePath, inputFileContents));
codeDoc.Items[BlazorCodeDocItems.Namespace] = combinedNamespace;
codeDoc.Items[BlazorCodeDocItems.ClassName] = itemClassName;
engine.Process(codeDoc);
var csharpDocument = codeDoc.GetCSharpDocument();
var csharpDocument = blazorTemplateEngine.GenerateCode(codeDoc);
var generatedCode = csharpDocument.GeneratedCode;
// Add parameters to the primary method via string manipulation because

View File

@ -15,6 +15,8 @@ namespace Microsoft.AspNetCore.Blazor.Razor
private readonly RazorEngine _engine;
private readonly RazorCodeGenerationOptions _codegenOptions;
public RazorEngine Engine => _engine;
public BlazorRazorEngine()
{
_codegenOptions = RazorCodeGenerationOptions.CreateDefault();
@ -39,8 +41,5 @@ namespace Microsoft.AspNetCore.Blazor.Razor
});
});
}
public void Process(RazorCodeDocument document)
=> _engine.Process(document);
}
}

View File

@ -0,0 +1,41 @@
// 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.IO;
using Microsoft.AspNetCore.Razor.Language;
using System.Text;
namespace Microsoft.AspNetCore.Blazor.Razor
{
/// <summary>
/// A <see cref="RazorTemplateEngine"/> for Blazor components.
/// </summary>
public class BlazorTemplateEngine : RazorTemplateEngine
{
public BlazorTemplateEngine(RazorEngine engine, RazorProject project)
: base(engine, project)
{
Options.ImportsFileName = "_ViewImports.cshtml";
Options.DefaultImports = GetDefaultImports();
}
private static RazorSourceDocument GetDefaultImports()
{
using (var stream = new MemoryStream())
using (var writer = new StreamWriter(stream, Encoding.UTF8))
{
// TODO: Add other commonly-used Blazor namespaces here. Can't do so yet
// because the tooling wouldn't know about it, so it would still look like
// an error if you hadn't explicitly imported them.
writer.WriteLine("@using System");
writer.WriteLine("@using System.Collections.Generic");
writer.WriteLine("@using System.Linq");
writer.WriteLine("@using System.Threading.Tasks");
writer.Flush();
stream.Position = 0;
return RazorSourceDocument.ReadFrom(stream, fileName: null, encoding: Encoding.UTF8);
}
}
}
}

View File

@ -496,7 +496,9 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
{
compilation.Emit(peStream);
var diagnostics = compilation.GetDiagnostics();
var diagnostics = compilation
.GetDiagnostics()
.Where(d => d.Severity != DiagnosticSeverity.Hidden);
return new CompileToAssemblyResult
{
Diagnostics = diagnostics,

View File

@ -3,8 +3,11 @@
using System;
using System.Collections.Generic;
using System.Configuration.Assemblies;
using System.Linq;
using System.Numerics;
using BasicTestApp;
using BasicTestApp.HierarchicalImportsTest.Subdir;
using Microsoft.AspNetCore.Blazor.Components;
using Microsoft.AspNetCore.Blazor.E2ETest.Infrastructure;
using Microsoft.AspNetCore.Blazor.E2ETest.Infrastructure.ServerFixtures;
@ -189,6 +192,17 @@ namespace Microsoft.AspNetCore.Blazor.E2ETest.Tests
Assert.Empty(fragmentElements);
}
[Fact]
public void CanUseViewImportsHierarchically()
{
// The component is able to compile and output these type names only because
// of the _ViewImports.cshtml files at the same and ancestor levels
var appElement = MountTestComponent<ComponentUsingImports>();
Assert.Collection(appElement.FindElements(By.TagName("p")),
elem => Assert.Equal(typeof(Complex).FullName, elem.Text),
elem => Assert.Equal(typeof(AssemblyHashAlgorithm).FullName, elem.Text));
}
private IWebElement MountTestComponent<TComponent>() where TComponent: IComponent
{
var componentTypeName = typeof(TComponent).FullName;

View File

@ -0,0 +1,5 @@
The following two outputs rely on "using" directives in _ViewImports files at the current and ancestor levels.
<p>@(typeof(Complex).FullName)</p>
<p>@(typeof(AssemblyHashAlgorithm).FullName)</p>

View File

@ -0,0 +1 @@
@using System.Configuration.Assemblies

View File

@ -0,0 +1 @@
@using System.Numerics