From f661021324fc0f015b9af70369e5a830d299e8fb Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Sun, 29 Apr 2018 22:14:58 -0700 Subject: [PATCH] Add [Parameter] for component parameters This change introduces ParameterAttribute to specify a bindable component parameter. As of the 0.3 release of Blazor we plan to make [Parameter] required to make a property bindable by callers. This also applies to parameters when their value is set by the infrastructure, such as `Body` for layouts, and route paramters. The rationale behind this change is that we think there is a need to separate the definition of properties from their suitability for a caller to set them through markup. We plan to introduce more features in this area in the future such as marking parameters as required. This is first step, and we think that this approach will scale nicely as we add more functionaly. The 0.3 release seems like the right time to change this behavior since we're also introducing `ref` for captures in this release. --- .../StandaloneApp/Shared/MainLayout.cshtml | 1 + .../BlazorApi.cs | 5 ++ .../ComponentTagHelperDescriptorProvider.cs | 26 ++++++-- .../Shared/SurveyPrompt.cshtml | 1 + .../Shared/SurveyPrompt.cshtml | 1 + .../Components/ParameterAttribute.cs | 15 +++++ .../ParameterCollectionExtensions.cs | 7 +++ .../Layouts/LayoutDisplay.cs | 2 + .../Routing/NavLink.cs | 2 + .../Routing/Router.cs | 1 + .../BindRazorIntegrationTest.cs | 4 ++ .../ComponentRenderingRazorIntegrationTest.cs | 46 ++++++++++++-- .../DesignTimeCodeGenerationTest.cs | 18 ++++-- .../DirectiveRazorIntegrationTest.cs | 1 + .../RuntimeCodeGenerationTest.cs | 17 ++++-- .../BindTagHelperDescriptorProviderTest.cs | 2 + ...omponentTagHelperDescriptorProviderTest.cs | 61 +++++++++++++++++++ .../LayoutTest.cs | 3 + .../RenderTreeDiffBuilderTest.cs | 11 ++++ .../RendererTest.cs | 17 ++++++ .../BasicTestApp/MessageComponent.cshtml | 5 +- .../PassThroughContentComponent.cshtml | 3 +- .../PropertiesChangedHandlerChild.cshtml | 4 +- .../RouterTest/WithParameters.cshtml | 3 + 24 files changed, 235 insertions(+), 21 deletions(-) create mode 100644 src/Microsoft.AspNetCore.Blazor/Components/ParameterAttribute.cs diff --git a/samples/StandaloneApp/Shared/MainLayout.cshtml b/samples/StandaloneApp/Shared/MainLayout.cshtml index 985a2ec2e6..7202cfb4a7 100644 --- a/samples/StandaloneApp/Shared/MainLayout.cshtml +++ b/samples/StandaloneApp/Shared/MainLayout.cshtml @@ -15,5 +15,6 @@ @functions { + [Parameter] public RenderFragment Body { get; set; } } diff --git a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/BlazorApi.cs b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/BlazorApi.cs index 581c3f6cda..8961ea5791 100644 --- a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/BlazorApi.cs +++ b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/BlazorApi.cs @@ -16,6 +16,11 @@ namespace Microsoft.AspNetCore.Blazor.Razor public static readonly string BuildRenderTree = nameof(BuildRenderTree); } + public static class ParameterAttribute + { + public static readonly string FullTypeName = "Microsoft.AspNetCore.Blazor.Components.ParameterAttribute"; + } + public static class LayoutAttribute { public static readonly string FullTypeName = "Microsoft.AspNetCore.Blazor.Layouts.LayoutAttribute"; diff --git a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/ComponentTagHelperDescriptorProvider.cs b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/ComponentTagHelperDescriptorProvider.cs index 9ba01f12e6..79df0b3840 100644 --- a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/ComponentTagHelperDescriptorProvider.cs +++ b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/ComponentTagHelperDescriptorProvider.cs @@ -42,6 +42,13 @@ namespace Microsoft.AspNetCore.Blazor.Razor return; } + var parameterSymbol = compilation.GetTypeByMetadataName(BlazorApi.ParameterAttribute.FullTypeName); + if (parameterSymbol == null) + { + // No definition for [Parameter], nothing to do. + return; + } + var types = new List(); var visitor = new ComponentTypeVisitor(componentSymbol, types); @@ -60,17 +67,22 @@ namespace Microsoft.AspNetCore.Blazor.Razor for (var i = 0; i < types.Count; i++) { var type = types[i]; - context.Results.Add(CreateDescriptor(type)); + context.Results.Add(CreateDescriptor(type, parameterSymbol)); } } - private TagHelperDescriptor CreateDescriptor(INamedTypeSymbol type) + private TagHelperDescriptor CreateDescriptor(INamedTypeSymbol type, INamedTypeSymbol parameterSymbol) { if (type == null) { throw new ArgumentNullException(nameof(type)); } + if (parameterSymbol == null) + { + throw new ArgumentNullException(nameof(parameterSymbol)); + } + var typeName = type.ToDisplayString(FullNameTypeDisplayFormat); var assemblyName = type.ContainingAssembly.Identity.Name; @@ -90,7 +102,7 @@ namespace Microsoft.AspNetCore.Blazor.Razor // Components have very simple matching rules. The type name (short) matches the tag name. builder.TagMatchingRule(r => r.TagName = type.Name); - foreach (var property in GetVisibleProperties(type)) + foreach (var property in GetProperties(type, parameterSymbol)) { if (property.kind == PropertyKind.Ignored) { @@ -134,7 +146,7 @@ namespace Microsoft.AspNetCore.Blazor.Razor // - has public getter // - has public setter // - is not an indexer - private IEnumerable<(IPropertySymbol property, PropertyKind kind)> GetVisibleProperties(INamedTypeSymbol type) + private IEnumerable<(IPropertySymbol property, PropertyKind kind)> GetProperties(INamedTypeSymbol type, INamedTypeSymbol parameterSymbol) { var properties = new Dictionary(StringComparer.Ordinal); do @@ -174,6 +186,12 @@ namespace Microsoft.AspNetCore.Blazor.Razor kind = PropertyKind.Ignored; } + if (!property.GetAttributes().Any(a => a.AttributeClass == parameterSymbol)) + { + // Does not have [Parameter] + kind = PropertyKind.Ignored; + } + if (kind == PropertyKind.Default && property.Type.TypeKind == TypeKind.Enum) { kind = PropertyKind.Enum; diff --git a/src/Microsoft.AspNetCore.Blazor.Templates/content/BlazorHosted.CSharp/BlazorHosted.CSharp.Client/Shared/SurveyPrompt.cshtml b/src/Microsoft.AspNetCore.Blazor.Templates/content/BlazorHosted.CSharp/BlazorHosted.CSharp.Client/Shared/SurveyPrompt.cshtml index 740ae82400..f1f7ffebac 100644 --- a/src/Microsoft.AspNetCore.Blazor.Templates/content/BlazorHosted.CSharp/BlazorHosted.CSharp.Client/Shared/SurveyPrompt.cshtml +++ b/src/Microsoft.AspNetCore.Blazor.Templates/content/BlazorHosted.CSharp/BlazorHosted.CSharp.Client/Shared/SurveyPrompt.cshtml @@ -14,5 +14,6 @@ @functions { // This is to demonstrate how a parent component can supply parameters + [Parameter] public string Title { get; set; } } diff --git a/src/Microsoft.AspNetCore.Blazor.Templates/content/BlazorStandalone.CSharp/Shared/SurveyPrompt.cshtml b/src/Microsoft.AspNetCore.Blazor.Templates/content/BlazorStandalone.CSharp/Shared/SurveyPrompt.cshtml index 740ae82400..f1f7ffebac 100644 --- a/src/Microsoft.AspNetCore.Blazor.Templates/content/BlazorStandalone.CSharp/Shared/SurveyPrompt.cshtml +++ b/src/Microsoft.AspNetCore.Blazor.Templates/content/BlazorStandalone.CSharp/Shared/SurveyPrompt.cshtml @@ -14,5 +14,6 @@ @functions { // This is to demonstrate how a parent component can supply parameters + [Parameter] public string Title { get; set; } } diff --git a/src/Microsoft.AspNetCore.Blazor/Components/ParameterAttribute.cs b/src/Microsoft.AspNetCore.Blazor/Components/ParameterAttribute.cs new file mode 100644 index 0000000000..c92f41fbd6 --- /dev/null +++ b/src/Microsoft.AspNetCore.Blazor/Components/ParameterAttribute.cs @@ -0,0 +1,15 @@ +// 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.Blazor.Components +{ + /// + /// Denotes the target member as a component parameter. + /// + [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)] + public sealed class ParameterAttribute : Attribute + { + } +} diff --git a/src/Microsoft.AspNetCore.Blazor/Components/ParameterCollectionExtensions.cs b/src/Microsoft.AspNetCore.Blazor/Components/ParameterCollectionExtensions.cs index 1f39d7df85..9ef5a2ea1d 100644 --- a/src/Microsoft.AspNetCore.Blazor/Components/ParameterCollectionExtensions.cs +++ b/src/Microsoft.AspNetCore.Blazor/Components/ParameterCollectionExtensions.cs @@ -66,6 +66,13 @@ namespace Microsoft.AspNetCore.Blazor.Components $"matching the name '{propertyName}'."); } + if (!property.IsDefined(typeof(ParameterAttribute))) + { + throw new InvalidOperationException( + $"Object of type '{targetType.FullName}' has a property matching the name '{propertyName}', " + + $"but it does not have [{nameof(ParameterAttribute)}] applied."); + } + return property; } } diff --git a/src/Microsoft.AspNetCore.Blazor/Layouts/LayoutDisplay.cs b/src/Microsoft.AspNetCore.Blazor/Layouts/LayoutDisplay.cs index dab3c7fba1..a7a938ba74 100644 --- a/src/Microsoft.AspNetCore.Blazor/Layouts/LayoutDisplay.cs +++ b/src/Microsoft.AspNetCore.Blazor/Layouts/LayoutDisplay.cs @@ -21,11 +21,13 @@ namespace Microsoft.AspNetCore.Blazor.Layouts /// Gets or sets the type of the page component to display. /// The type must implement . /// + [Parameter] public Type Page { get; set; } /// /// Gets or sets the parameters to pass to the page. /// + [Parameter] public IDictionary PageParameters { get; set; } /// diff --git a/src/Microsoft.AspNetCore.Blazor/Routing/NavLink.cs b/src/Microsoft.AspNetCore.Blazor/Routing/NavLink.cs index 2cfff8ccdf..bf34012707 100644 --- a/src/Microsoft.AspNetCore.Blazor/Routing/NavLink.cs +++ b/src/Microsoft.AspNetCore.Blazor/Routing/NavLink.cs @@ -38,11 +38,13 @@ namespace Microsoft.AspNetCore.Blazor.Routing /// Gets or sets the CSS class name applied to the NavLink when the /// current route matches the NavLink href. /// + [Parameter] public string ActiveClass { get; set; } /// /// Gets or sets a value representing the URL matching behavior. /// + [Parameter] public NavLinkMatch Match { get; set; } [Inject] private IUriHelper UriHelper { get; set; } diff --git a/src/Microsoft.AspNetCore.Blazor/Routing/Router.cs b/src/Microsoft.AspNetCore.Blazor/Routing/Router.cs index bfbfef651c..5909ee297f 100644 --- a/src/Microsoft.AspNetCore.Blazor/Routing/Router.cs +++ b/src/Microsoft.AspNetCore.Blazor/Routing/Router.cs @@ -29,6 +29,7 @@ namespace Microsoft.AspNetCore.Blazor.Routing /// Gets or sets the assembly that should be searched, along with its referenced /// assemblies, for components matching the URI. /// + [Parameter] public Assembly AppAssembly { get; set; } private RouteTable Routes { get; set; } diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/BindRazorIntegrationTest.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/BindRazorIntegrationTest.cs index deef58edeb..00f171c1f6 100644 --- a/test/Microsoft.AspNetCore.Blazor.Build.Test/BindRazorIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/BindRazorIntegrationTest.cs @@ -24,8 +24,10 @@ namespace Test { public class MyComponent : BlazorComponent { + [Parameter] public int Value { get; set; } + [Parameter] public Action ValueChanged { get; set; } } }")); @@ -96,8 +98,10 @@ namespace Test { public class MyComponent : BlazorComponent { + [Parameter] public int Value { get; set; } + [Parameter] public Action OnChanged { get; set; } } }")); diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/ComponentRenderingRazorIntegrationTest.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/ComponentRenderingRazorIntegrationTest.cs index 70435e2ff0..c67bb05357 100644 --- a/test/Microsoft.AspNetCore.Blazor.Build.Test/ComponentRenderingRazorIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/ComponentRenderingRazorIntegrationTest.cs @@ -57,10 +57,10 @@ namespace Test public class MyComponent : BlazorComponent { - public int IntProperty { get; set; } - public bool BoolProperty { get; set; } - public string StringProperty { get; set; } - public SomeType ObjectProperty { get; set; } + [Parameter] public int IntProperty { get; set; } + [Parameter] public bool BoolProperty { get; set; } + [Parameter] public string StringProperty { get; set; } + [Parameter] public SomeType ObjectProperty { get; set; } } } ")); @@ -90,6 +90,36 @@ namespace Test }); } + [Fact] + public void Render_ChildComponent_TriesToSetNonParamter() + { + // Arrange + AdditionalSyntaxTrees.Add(Parse(@" +using Microsoft.AspNetCore.Blazor.Components; + +namespace Test +{ + public class MyComponent : BlazorComponent + { + public int IntProperty { get; set; } + } +} +")); + + var component = CompileToComponent(@" +@addTagHelper *, TestAssembly +"); + + // Act + var ex = Assert.Throws(() => GetRenderTree(component)); + + // Assert + Assert.Equal( + "Object of type 'Test.MyComponent' has a property matching the name 'IntProperty', " + + "but it does not have [ParameterAttribute] applied.", + ex.Message); + } + [Fact] public void Render_ChildComponent_WithExplicitStringParameter() { @@ -101,6 +131,7 @@ namespace Test { public class MyComponent : BlazorComponent { + [Parameter] public string StringProperty { get; set; } } } @@ -174,6 +205,7 @@ namespace Test { public class MyComponent : BlazorComponent { + [Parameter] public Action OnClick { get; set; } } } @@ -221,6 +253,7 @@ namespace Test { public class MyComponent : BlazorComponent { + [Parameter] public Action OnClick { get; set; } } } @@ -267,6 +300,7 @@ namespace Test { public class MyComponent : BlazorComponent { + [Parameter] public bool BoolProperty { get; set; } } }")); @@ -296,7 +330,10 @@ namespace Test { public class MyComponent : BlazorComponent { + [Parameter] public string MyAttr { get; set; } + + [Parameter] public RenderFragment ChildContent { get; set; } } } @@ -338,6 +375,7 @@ namespace Test { public class MyComponent : BlazorComponent { + [Parameter] public RenderFragment ChildContent { get; set; } } } diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/DesignTimeCodeGenerationTest.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/DesignTimeCodeGenerationTest.cs index 6d61482ed3..f5b6c31328 100644 --- a/test/Microsoft.AspNetCore.Blazor.Build.Test/DesignTimeCodeGenerationTest.cs +++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/DesignTimeCodeGenerationTest.cs @@ -1,7 +1,6 @@ // 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.CodeAnalysis.CSharp; using Xunit; namespace Microsoft.AspNetCore.Blazor.Build.Test @@ -27,10 +26,10 @@ namespace Test public class MyComponent : BlazorComponent { - public int IntProperty { get; set; } - public bool BoolProperty { get; set; } - public string StringProperty { get; set; } - public SomeType ObjectProperty { get; set; } + [Parameter] public int IntProperty { get; set; } + [Parameter] public bool BoolProperty { get; set; } + [Parameter] public string StringProperty { get; set; } + [Parameter] public SomeType ObjectProperty { get; set; } } } ")); @@ -61,6 +60,7 @@ namespace Test { public class MyComponent : BlazorComponent { + [Parameter] public string StringProperty { get; set; } } } @@ -116,6 +116,7 @@ namespace Test { public class MyComponent : BlazorComponent { + [Parameter] public Action OnClick { get; set; } } } @@ -152,6 +153,7 @@ namespace Test { public class MyComponent : BlazorComponent { + [Parameter] public Action OnClick { get; set; } } } @@ -188,8 +190,10 @@ namespace Test { public class MyComponent : BlazorComponent { + [Parameter] public string MyAttr { get; set; } + [Parameter] public RenderFragment ChildContent { get; set; } } } @@ -382,8 +386,10 @@ namespace Test { public class MyComponent : BlazorComponent { + [Parameter] public int Value { get; set; } + [Parameter] public Action ValueChanged { get; set; } } }")); @@ -446,8 +452,10 @@ namespace Test { public class MyComponent : BlazorComponent { + [Parameter] public int Value { get; set; } + [Parameter] public Action OnChanged { get; set; } } }")); diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/DirectiveRazorIntegrationTest.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/DirectiveRazorIntegrationTest.cs index 8cc58b1b61..5b7e7a49c3 100644 --- a/test/Microsoft.AspNetCore.Blazor.Build.Test/DirectiveRazorIntegrationTest.cs +++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/DirectiveRazorIntegrationTest.cs @@ -121,6 +121,7 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test public class TestLayout : ILayoutComponent { + [Parameter] public RenderFragment Body { get; set; } public void Init(RenderHandle renderHandle) diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/RuntimeCodeGenerationTest.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/RuntimeCodeGenerationTest.cs index 4c38e6298d..d6ddfadfce 100644 --- a/test/Microsoft.AspNetCore.Blazor.Build.Test/RuntimeCodeGenerationTest.cs +++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/RuntimeCodeGenerationTest.cs @@ -51,10 +51,10 @@ namespace Test public class MyComponent : BlazorComponent { - public int IntProperty { get; set; } - public bool BoolProperty { get; set; } - public string StringProperty { get; set; } - public SomeType ObjectProperty { get; set; } + [Parameter] public int IntProperty { get; set; } + [Parameter] public bool BoolProperty { get; set; } + [Parameter] public string StringProperty { get; set; } + [Parameter] public SomeType ObjectProperty { get; set; } } } ")); @@ -85,6 +85,7 @@ namespace Test { public class MyComponent : BlazorComponent { + [Parameter] public string StringProperty { get; set; } } } @@ -141,6 +142,7 @@ namespace Test { public class MyComponent : BlazorComponent { + [Parameter] public Action OnClick { get; set; } } } @@ -177,6 +179,7 @@ namespace Test { public class MyComponent : BlazorComponent { + [Parameter] public Action OnClick { get; set; } } } @@ -213,8 +216,10 @@ namespace Test { public class MyComponent : BlazorComponent { + [Parameter] public string MyAttr { get; set; } + [Parameter] public RenderFragment ChildContent { get; set; } } } @@ -635,8 +640,10 @@ namespace Test { public class MyComponent : BlazorComponent { + [Parameter] public int Value { get; set; } + [Parameter] public Action ValueChanged { get; set; } } }")); @@ -699,8 +706,10 @@ namespace Test { public class MyComponent : BlazorComponent { + [Parameter] public int Value { get; set; } + [Parameter] public Action OnChanged { get; set; } } }")); diff --git a/test/Microsoft.AspNetCore.Blazor.Razor.Extensions.Test/BindTagHelperDescriptorProviderTest.cs b/test/Microsoft.AspNetCore.Blazor.Razor.Extensions.Test/BindTagHelperDescriptorProviderTest.cs index a5755e1962..737f190687 100644 --- a/test/Microsoft.AspNetCore.Blazor.Razor.Extensions.Test/BindTagHelperDescriptorProviderTest.cs +++ b/test/Microsoft.AspNetCore.Blazor.Razor.Extensions.Test/BindTagHelperDescriptorProviderTest.cs @@ -27,8 +27,10 @@ namespace Test public void SetParameters(ParameterCollection parameters) { } + [Parameter] public string MyProperty { get; set; } + [Parameter] public Action MyPropertyChanged { get; set; } } } diff --git a/test/Microsoft.AspNetCore.Blazor.Razor.Extensions.Test/ComponentTagHelperDescriptorProviderTest.cs b/test/Microsoft.AspNetCore.Blazor.Razor.Extensions.Test/ComponentTagHelperDescriptorProviderTest.cs index ce94193e1a..e74476b132 100644 --- a/test/Microsoft.AspNetCore.Blazor.Razor.Extensions.Test/ComponentTagHelperDescriptorProviderTest.cs +++ b/test/Microsoft.AspNetCore.Blazor.Razor.Extensions.Test/ComponentTagHelperDescriptorProviderTest.cs @@ -27,6 +27,7 @@ namespace Test public void SetParameters(ParameterCollection parameters) { } + [Parameter] public string MyProperty { get; set; } } } @@ -136,6 +137,7 @@ namespace Test { public class MyComponent : BlazorComponent { + [Parameter] public string MyProperty { get; set; } } } @@ -176,6 +178,7 @@ namespace Test { public class MyComponent : BlazorComponent { + [Parameter] public bool MyProperty { get; set; } } } @@ -227,6 +230,7 @@ namespace Test public class MyComponent : BlazorComponent { + [Parameter] public MyEnum MyProperty { get; set; } } } @@ -274,6 +278,7 @@ namespace Test { public class MyComponent : BlazorComponent { + [Parameter] public Action OnClick { get; set; } } } @@ -307,5 +312,61 @@ namespace Test Assert.False(attribute.IsStringProperty); Assert.True(attribute.IsDelegateProperty()); } + + [Fact] // This component has lots of properties that don't become components. + public void Execute_IgnoredProperties_CreatesDescriptor() + { + // Arrange + + var compilation = BaseCompilation.AddSyntaxTrees(Parse(@" +using Microsoft.AspNetCore.Blazor.Components; + +namespace Test +{ + public abstract class MyBase : BlazorComponent + { + [Parameter] + public string Hidden { get; set; } + } + + public class MyComponent : MyBase + { + [Parameter] + public string NoPublicGetter { private get; set; } + + public string NoParameterAttribute { get; set; } + + // No attribute here, hides base-class property of the same name. + public new int Hidden { get; set; } + + public string this[int i] + { + get { throw null; } + set { throw null; } + } + } +} + +")); + + Assert.Empty(compilation.GetDiagnostics()); + + var context = TagHelperDescriptorProviderContext.Create(); + context.SetCompilation(compilation); + + var provider = new ComponentTagHelperDescriptorProvider(); + + // Act + provider.Execute(context); + + // Assert + var components = ExcludeBuiltInComponents(context); + var component = Assert.Single(components); + + Assert.Equal("TestAssembly", component.AssemblyName); + Assert.Equal("Test.MyComponent", component.Name); + + Assert.Empty(component.BoundAttributes); + } } } diff --git a/test/Microsoft.AspNetCore.Blazor.Test/LayoutTest.cs b/test/Microsoft.AspNetCore.Blazor.Test/LayoutTest.cs index 3a16601478..c303fbbee3 100644 --- a/test/Microsoft.AspNetCore.Blazor.Test/LayoutTest.cs +++ b/test/Microsoft.AspNetCore.Blazor.Test/LayoutTest.cs @@ -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.Blazor.Components; using Microsoft.AspNetCore.Blazor.Layouts; using Microsoft.AspNetCore.Blazor.RenderTree; using Microsoft.AspNetCore.Blazor.Test.Helpers; @@ -219,6 +220,7 @@ namespace Microsoft.AspNetCore.Blazor.Test private class RootLayout : AutoRenderComponent, ILayoutComponent { + [Parameter] public RenderFragment Body { get; set; } protected override void BuildRenderTree(RenderTreeBuilder builder) @@ -232,6 +234,7 @@ namespace Microsoft.AspNetCore.Blazor.Test [Layout(typeof(RootLayout))] private class NestedLayout : AutoRenderComponent, ILayoutComponent { + [Parameter] public RenderFragment Body { get; set; } protected override void BuildRenderTree(RenderTreeBuilder builder) diff --git a/test/Microsoft.AspNetCore.Blazor.Test/RenderTreeDiffBuilderTest.cs b/test/Microsoft.AspNetCore.Blazor.Test/RenderTreeDiffBuilderTest.cs index 00598122dd..a53c433ae6 100644 --- a/test/Microsoft.AspNetCore.Blazor.Test/RenderTreeDiffBuilderTest.cs +++ b/test/Microsoft.AspNetCore.Blazor.Test/RenderTreeDiffBuilderTest.cs @@ -1503,12 +1503,23 @@ namespace Microsoft.AspNetCore.Blazor.Test private class FakeComponent : IComponent { + [Parameter] public int IntProperty { get; set; } + + [Parameter] public string StringProperty { get; set; } + + [Parameter] public object ObjectProperty { get; set; } + + [Parameter] public string ReadonlyProperty { get; private set; } + + [Parameter] private string PrivateProperty { get; set; } + public string NonParameterProperty { get; set; } + public void Init(RenderHandle renderHandle) { } public void SetParameters(ParameterCollection parameters) { diff --git a/test/Microsoft.AspNetCore.Blazor.Test/RendererTest.cs b/test/Microsoft.AspNetCore.Blazor.Test/RendererTest.cs index 87ba995fe7..af7215c3a4 100644 --- a/test/Microsoft.AspNetCore.Blazor.Test/RendererTest.cs +++ b/test/Microsoft.AspNetCore.Blazor.Test/RendererTest.cs @@ -1109,6 +1109,7 @@ namespace Microsoft.AspNetCore.Blazor.Test private class MessageComponent : AutoRenderComponent { + [Parameter] public string Message { get; set; } protected override void BuildRenderTree(RenderTreeBuilder builder) @@ -1119,9 +1120,15 @@ namespace Microsoft.AspNetCore.Blazor.Test private class FakeComponent : IComponent { + [Parameter] public int IntProperty { get; set; } + + [Parameter] public string StringProperty { get; set; } + + [Parameter] public object ObjectProperty { get; set; } + public RenderHandle RenderHandle { get; private set; } public void Init(RenderHandle renderHandle) @@ -1133,8 +1140,13 @@ namespace Microsoft.AspNetCore.Blazor.Test private class EventComponent : AutoRenderComponent, IComponent, IHandleEvent { + [Parameter] public Action OnTest { get; set; } + + [Parameter] public Action OnClick { get; set; } + + [Parameter] public Action OnClickAction { get; set; } public bool SkipElement { get; set; } @@ -1174,7 +1186,10 @@ namespace Microsoft.AspNetCore.Blazor.Test private class ConditionalParentComponent : AutoRenderComponent where T : IComponent { + [Parameter] public bool IncludeChild { get; set; } + + [Parameter] public IDictionary ChildParameters { get; set; } protected override void BuildRenderTree(RenderTreeBuilder builder) @@ -1199,6 +1214,7 @@ namespace Microsoft.AspNetCore.Blazor.Test private class ReRendersParentComponent : AutoRenderComponent { + [Parameter] public TestComponent Parent { get; set; } private bool _isFirstTime = true; @@ -1216,6 +1232,7 @@ namespace Microsoft.AspNetCore.Blazor.Test private class RendersSelfAfterEventComponent : IComponent, IHandleEvent { + [Parameter] public Action OnClick { get; set; } private RenderHandle _renderHandle; diff --git a/test/testapps/BasicTestApp/MessageComponent.cshtml b/test/testapps/BasicTestApp/MessageComponent.cshtml index 51ce2cc47d..24845cacc1 100644 --- a/test/testapps/BasicTestApp/MessageComponent.cshtml +++ b/test/testapps/BasicTestApp/MessageComponent.cshtml @@ -1,4 +1,5 @@ -@Message +@using Microsoft.AspNetCore.Blazor.Components +@Message @functions { - public string Message { get; set; } + [Parameter] public string Message { get; set; } } diff --git a/test/testapps/BasicTestApp/PassThroughContentComponent.cshtml b/test/testapps/BasicTestApp/PassThroughContentComponent.cshtml index 796347b04f..b9f2d947da 100644 --- a/test/testapps/BasicTestApp/PassThroughContentComponent.cshtml +++ b/test/testapps/BasicTestApp/PassThroughContentComponent.cshtml @@ -1,8 +1,9 @@ @using Microsoft.AspNetCore.Blazor +@using Microsoft.AspNetCore.Blazor.Components @ChildContent @functions { // Note: The lack of any whitespace or other output besides @ChildContent is important for // what scenarios this component is used for in E2E tests. - public RenderFragment ChildContent { get; set; } + [Parameter] public RenderFragment ChildContent { get; set; } } diff --git a/test/testapps/BasicTestApp/PropertiesChangedHandlerChild.cshtml b/test/testapps/BasicTestApp/PropertiesChangedHandlerChild.cshtml index caa5c46849..01982d241d 100644 --- a/test/testapps/BasicTestApp/PropertiesChangedHandlerChild.cshtml +++ b/test/testapps/BasicTestApp/PropertiesChangedHandlerChild.cshtml @@ -1,7 +1,9 @@ -
You supplied: @SuppliedValue
+@using Microsoft.AspNetCore.Blazor.Components +
You supplied: @SuppliedValue
I computed: @computedValue
@functions { + [Parameter] public int SuppliedValue { get; set; } private int computedValue; diff --git a/test/testapps/BasicTestApp/RouterTest/WithParameters.cshtml b/test/testapps/BasicTestApp/RouterTest/WithParameters.cshtml index b213ef4845..1b54e1348f 100644 --- a/test/testapps/BasicTestApp/RouterTest/WithParameters.cshtml +++ b/test/testapps/BasicTestApp/RouterTest/WithParameters.cshtml @@ -1,11 +1,14 @@ @page "/RouterTest/WithParameters/Name/{firstName}/LastName/{lastName}" @using BasicTestApp.RouterTest +@using Microsoft.AspNetCore.Blazor.Components
Your full name is @FirstName @LastName.
@functions { + [Parameter] public string FirstName { get; set; } + [Parameter] public string LastName { get ; set; } }