Define ILayoutComponent so there's compile-time validation that layouts are defined correctly
This commit is contained in:
parent
7139cb70c5
commit
f54df27c21
|
|
@ -14,6 +14,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Blazor.Components;
|
using Microsoft.AspNetCore.Blazor.Components;
|
||||||
|
using Microsoft.AspNetCore.Blazor.Layouts;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc
|
namespace Microsoft.AspNetCore.Mvc
|
||||||
|
|
@ -28,7 +29,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
|
||||||
{
|
{
|
||||||
// This is temporary and exists only to support TemporaryLayoutPass.
|
// This is temporary and exists only to support TemporaryLayoutPass.
|
||||||
// It will be removed when we can add Blazor-specific directives.
|
// It will be removed when we can add Blazor-specific directives.
|
||||||
public object Layout<TLayout>() where TLayout : IComponent
|
public object Layout<TLayout>() where TLayout : ILayoutComponent
|
||||||
=> throw new NotImplementedException();
|
=> throw new NotImplementedException();
|
||||||
|
|
||||||
// Similar temporary mechanism as above
|
// Similar temporary mechanism as above
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
// 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.Blazor.Components;
|
||||||
|
using Microsoft.AspNetCore.Blazor.RenderTree;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Blazor.Layouts
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Indicates that the type represents a layout.
|
||||||
|
/// </summary>
|
||||||
|
public interface ILayoutComponent : IComponent
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the content to be rendered inside the layout.
|
||||||
|
/// </summary>
|
||||||
|
RenderFragment Body { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Blazor.Components;
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Blazor.Layouts
|
namespace Microsoft.AspNetCore.Blazor.Layouts
|
||||||
|
|
@ -13,22 +12,22 @@ namespace Microsoft.AspNetCore.Blazor.Layouts
|
||||||
public class LayoutAttribute : Attribute
|
public class LayoutAttribute : Attribute
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The type of the layout. The type always implements <see cref="IComponent"/>.
|
/// The type of the layout. The type always implements <see cref="ILayoutComponent"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Type LayoutType { get; private set; }
|
public Type LayoutType { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructs an instance of <see cref="LayoutAttribute"/>.
|
/// Constructs an instance of <see cref="LayoutAttribute"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="layoutType">The type of the layout. This must implement <see cref="IComponent"/>.</param>
|
/// <param name="layoutType">The type of the layout. This must implement <see cref="ILayoutComponent"/>.</param>
|
||||||
public LayoutAttribute(Type layoutType)
|
public LayoutAttribute(Type layoutType)
|
||||||
{
|
{
|
||||||
LayoutType = layoutType ?? throw new ArgumentNullException(nameof(layoutType));
|
LayoutType = layoutType ?? throw new ArgumentNullException(nameof(layoutType));
|
||||||
|
|
||||||
if (!typeof(IComponent).IsAssignableFrom(layoutType))
|
if (!typeof(ILayoutComponent).IsAssignableFrom(layoutType))
|
||||||
{
|
{
|
||||||
throw new ArgumentException($"Invalid layout type: {layoutType.FullName} " +
|
throw new ArgumentException($"Invalid layout type: {layoutType.FullName} " +
|
||||||
$"does not implement {typeof(IComponent).FullName}.");
|
$"does not implement {typeof(ILayoutComponent).FullName}.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -375,7 +375,7 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
|
||||||
public void SupportsLayoutDeclarationsViaTemporarySyntax()
|
public void SupportsLayoutDeclarationsViaTemporarySyntax()
|
||||||
{
|
{
|
||||||
// Arrange/Act
|
// Arrange/Act
|
||||||
var testComponentTypeName = typeof(TestComponent).FullName.Replace('+', '.');
|
var testComponentTypeName = typeof(TestLayout).FullName.Replace('+', '.');
|
||||||
var component = CompileToComponent(
|
var component = CompileToComponent(
|
||||||
$"@(Layout<{testComponentTypeName}>())" +
|
$"@(Layout<{testComponentTypeName}>())" +
|
||||||
$"Hello");
|
$"Hello");
|
||||||
|
|
@ -384,7 +384,7 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
|
||||||
// Assert
|
// Assert
|
||||||
var layoutAttribute = component.GetType().GetCustomAttribute<LayoutAttribute>();
|
var layoutAttribute = component.GetType().GetCustomAttribute<LayoutAttribute>();
|
||||||
Assert.NotNull(layoutAttribute);
|
Assert.NotNull(layoutAttribute);
|
||||||
Assert.Equal(typeof(TestComponent), layoutAttribute.LayoutType);
|
Assert.Equal(typeof(TestLayout), layoutAttribute.LayoutType);
|
||||||
Assert.Collection(frames,
|
Assert.Collection(frames,
|
||||||
frame => AssertFrame.Text(frame, "Hello"));
|
frame => AssertFrame.Text(frame, "Hello"));
|
||||||
}
|
}
|
||||||
|
|
@ -540,6 +540,19 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class TestLayout : ILayoutComponent
|
||||||
|
{
|
||||||
|
public RenderFragment Body { get; set; }
|
||||||
|
|
||||||
|
public void Init(RenderHandle renderHandle)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetParameters(ParameterCollection parameters)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public interface ITestInterface { }
|
public interface ITestInterface { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue