From 63a4b5c27ab98b592fbc3808efda5f6eaaaab959 Mon Sep 17 00:00:00 2001 From: Steve Sanderson Date: Wed, 27 Mar 2019 21:26:13 +0000 Subject: [PATCH] Fix rendering inheritance. Fixes #8192 (#8818) * Make it irrelevant whether components call base.BuildRenderTree or not. Fixes #8192 * Remove base.BuildRenderTree calls from manually-implemented render logic * Update ref assembly code --- .../ComponentRenderingRazorIntegrationTest.cs | 1 - ...soft.AspNetCore.Components.netstandard2.0.cs | 1 - src/Components/Components/src/ComponentBase.cs | 17 +++++++++-------- src/Components/Components/src/Forms/EditForm.cs | 2 -- .../src/Forms/InputComponents/InputCheckbox.cs | 1 - .../src/Forms/InputComponents/InputDate.cs | 1 - .../src/Forms/InputComponents/InputNumber.cs | 1 - .../src/Forms/InputComponents/InputSelect.cs | 1 - .../src/Forms/InputComponents/InputText.cs | 1 - .../src/Forms/InputComponents/InputTextArea.cs | 1 - .../Components/src/Forms/ValidationMessage.cs | 2 -- .../Components/src/Forms/ValidationSummary.cs | 2 -- .../Components/test/ComponentBaseTest.cs | 1 - src/Components/Components/test/RendererTest.cs | 1 - .../test/Rendering/HtmlRendererTestBase.cs | 2 -- 15 files changed, 9 insertions(+), 26 deletions(-) diff --git a/src/Components/Blazor/Build/test/ComponentRenderingRazorIntegrationTest.cs b/src/Components/Blazor/Build/test/ComponentRenderingRazorIntegrationTest.cs index b31811aa4b..252183da65 100644 --- a/src/Components/Blazor/Build/test/ComponentRenderingRazorIntegrationTest.cs +++ b/src/Components/Blazor/Build/test/ComponentRenderingRazorIntegrationTest.cs @@ -577,7 +577,6 @@ namespace Test protected override void BuildRenderTree(RenderTreeBuilder builder) { - base.BuildRenderTree(builder); for (var i = 0; i < Count; i++) { builder.AddContent(i, Template, Value); diff --git a/src/Components/Components/ref/Microsoft.AspNetCore.Components.netstandard2.0.cs b/src/Components/Components/ref/Microsoft.AspNetCore.Components.netstandard2.0.cs index 25e84ceac4..77ce77402b 100644 --- a/src/Components/Components/ref/Microsoft.AspNetCore.Components.netstandard2.0.cs +++ b/src/Components/Components/ref/Microsoft.AspNetCore.Components.netstandard2.0.cs @@ -65,7 +65,6 @@ namespace Microsoft.AspNetCore.Components } public abstract partial class ComponentBase : Microsoft.AspNetCore.Components.IComponent, Microsoft.AspNetCore.Components.IHandleAfterRender, Microsoft.AspNetCore.Components.IHandleEvent { - public const string BuildRenderTreeMethodName = "BuildRenderTree"; public ComponentBase() { } protected virtual void BuildRenderTree(Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder) { } protected System.Threading.Tasks.Task Invoke(System.Action workItem) { throw null; } diff --git a/src/Components/Components/src/ComponentBase.cs b/src/Components/Components/src/ComponentBase.cs index a2ea3c906b..7333a0020f 100644 --- a/src/Components/Components/src/ComponentBase.cs +++ b/src/Components/Components/src/ComponentBase.cs @@ -25,11 +25,6 @@ namespace Microsoft.AspNetCore.Components /// public abstract class ComponentBase : IComponent, IHandleEvent, IHandleAfterRender { - /// - /// Specifies the name of the -building method. - /// - public const string BuildRenderTreeMethodName = nameof(BuildRenderTree); - private readonly RenderFragment _renderFragment; private RenderHandle _renderHandle; private bool _initialized; @@ -41,7 +36,12 @@ namespace Microsoft.AspNetCore.Components /// public ComponentBase() { - _renderFragment = BuildRenderTree; + _renderFragment = builder => + { + _hasPendingQueuedRender = false; + _hasNeverRendered = false; + BuildRenderTree(builder); + }; } /// @@ -52,8 +52,9 @@ namespace Microsoft.AspNetCore.Components { // Developers can either override this method in derived classes, or can use Razor // syntax to define a derived class and have the compiler generate the method. - _hasPendingQueuedRender = false; - _hasNeverRendered = false; + + // Other code within this class should *not* invoke BuildRenderTree directly, + // but instead should invoke the _renderFragment field. } /// diff --git a/src/Components/Components/src/Forms/EditForm.cs b/src/Components/Components/src/Forms/EditForm.cs index 8469896558..2041144bdb 100644 --- a/src/Components/Components/src/Forms/EditForm.cs +++ b/src/Components/Components/src/Forms/EditForm.cs @@ -93,8 +93,6 @@ namespace Microsoft.AspNetCore.Components.Forms /// protected override void BuildRenderTree(RenderTreeBuilder builder) { - base.BuildRenderTree(builder); - // If _fixedEditContext changes, tear down and recreate all descendants. // This is so we can safely use the IsFixed optimization on CascadingValue, // optimizing for the common case where _fixedEditContext never changes. diff --git a/src/Components/Components/src/Forms/InputComponents/InputCheckbox.cs b/src/Components/Components/src/Forms/InputComponents/InputCheckbox.cs index 4ccef84347..673cf98787 100644 --- a/src/Components/Components/src/Forms/InputComponents/InputCheckbox.cs +++ b/src/Components/Components/src/Forms/InputComponents/InputCheckbox.cs @@ -23,7 +23,6 @@ namespace Microsoft.AspNetCore.Components.Forms /// protected override void BuildRenderTree(RenderTreeBuilder builder) { - base.BuildRenderTree(builder); builder.OpenElement(0, "input"); builder.AddAttribute(1, "type", "checkbox"); builder.AddAttribute(2, "id", Id); diff --git a/src/Components/Components/src/Forms/InputComponents/InputDate.cs b/src/Components/Components/src/Forms/InputComponents/InputDate.cs index 2c1a162eb9..5f794d4813 100644 --- a/src/Components/Components/src/Forms/InputComponents/InputDate.cs +++ b/src/Components/Components/src/Forms/InputComponents/InputDate.cs @@ -22,7 +22,6 @@ namespace Microsoft.AspNetCore.Components.Forms /// protected override void BuildRenderTree(RenderTreeBuilder builder) { - base.BuildRenderTree(builder); builder.OpenElement(0, "input"); builder.AddAttribute(1, "type", "date"); builder.AddAttribute(2, "id", Id); diff --git a/src/Components/Components/src/Forms/InputComponents/InputNumber.cs b/src/Components/Components/src/Forms/InputComponents/InputNumber.cs index 0c4b8c30d4..8433454a2e 100644 --- a/src/Components/Components/src/Forms/InputComponents/InputNumber.cs +++ b/src/Components/Components/src/Forms/InputComponents/InputNumber.cs @@ -61,7 +61,6 @@ namespace Microsoft.AspNetCore.Components.Forms /// protected override void BuildRenderTree(RenderTreeBuilder builder) { - base.BuildRenderTree(builder); builder.OpenElement(0, "input"); builder.AddAttribute(1, "type", "number"); builder.AddAttribute(2, "step", _stepAttributeValue); diff --git a/src/Components/Components/src/Forms/InputComponents/InputSelect.cs b/src/Components/Components/src/Forms/InputComponents/InputSelect.cs index 9fbf3de63a..cee64cb281 100644 --- a/src/Components/Components/src/Forms/InputComponents/InputSelect.cs +++ b/src/Components/Components/src/Forms/InputComponents/InputSelect.cs @@ -19,7 +19,6 @@ namespace Microsoft.AspNetCore.Components.Forms /// protected override void BuildRenderTree(RenderTreeBuilder builder) { - base.BuildRenderTree(builder); builder.OpenElement(0, "select"); builder.AddAttribute(1, "id", Id); builder.AddAttribute(2, "class", CssClass); diff --git a/src/Components/Components/src/Forms/InputComponents/InputText.cs b/src/Components/Components/src/Forms/InputComponents/InputText.cs index 44c7eaf6ea..71657b13f8 100644 --- a/src/Components/Components/src/Forms/InputComponents/InputText.cs +++ b/src/Components/Components/src/Forms/InputComponents/InputText.cs @@ -24,7 +24,6 @@ namespace Microsoft.AspNetCore.Components.Forms /// protected override void BuildRenderTree(RenderTreeBuilder builder) { - base.BuildRenderTree(builder); builder.OpenElement(0, "input"); builder.AddAttribute(1, "id", Id); builder.AddAttribute(2, "class", CssClass); diff --git a/src/Components/Components/src/Forms/InputComponents/InputTextArea.cs b/src/Components/Components/src/Forms/InputComponents/InputTextArea.cs index 2ddc5cf3be..72c9563d7d 100644 --- a/src/Components/Components/src/Forms/InputComponents/InputTextArea.cs +++ b/src/Components/Components/src/Forms/InputComponents/InputTextArea.cs @@ -24,7 +24,6 @@ namespace Microsoft.AspNetCore.Components.Forms /// protected override void BuildRenderTree(RenderTreeBuilder builder) { - base.BuildRenderTree(builder); builder.OpenElement(0, "textarea"); builder.AddAttribute(1, "id", Id); builder.AddAttribute(2, "class", CssClass); diff --git a/src/Components/Components/src/Forms/ValidationMessage.cs b/src/Components/Components/src/Forms/ValidationMessage.cs index be026b7f34..bb2c861de0 100644 --- a/src/Components/Components/src/Forms/ValidationMessage.cs +++ b/src/Components/Components/src/Forms/ValidationMessage.cs @@ -64,8 +64,6 @@ namespace Microsoft.AspNetCore.Components.Forms /// protected override void BuildRenderTree(RenderTreeBuilder builder) { - base.BuildRenderTree(builder); - foreach (var message in CurrentEditContext.GetValidationMessages(_fieldIdentifier)) { builder.OpenElement(0, "div"); diff --git a/src/Components/Components/src/Forms/ValidationSummary.cs b/src/Components/Components/src/Forms/ValidationSummary.cs index 094b7779fc..0159f1be31 100644 --- a/src/Components/Components/src/Forms/ValidationSummary.cs +++ b/src/Components/Components/src/Forms/ValidationSummary.cs @@ -49,8 +49,6 @@ namespace Microsoft.AspNetCore.Components.Forms /// protected override void BuildRenderTree(RenderTreeBuilder builder) { - base.BuildRenderTree(builder); - // As an optimization, only evaluate the messages enumerable once, and // only produce the enclosing
    if there's at least one message var messagesEnumerator = CurrentEditContext.GetValidationMessages().GetEnumerator(); diff --git a/src/Components/Components/test/ComponentBaseTest.cs b/src/Components/Components/test/ComponentBaseTest.cs index 7d14fc8c34..15c2ae98c2 100644 --- a/src/Components/Components/test/ComponentBaseTest.cs +++ b/src/Components/Components/test/ComponentBaseTest.cs @@ -380,7 +380,6 @@ namespace Microsoft.AspNetCore.Components.Test protected override void BuildRenderTree(RenderTreeBuilder builder) { - base.BuildRenderTree(builder); builder.OpenElement(0, "p"); builder.AddContent(1, Counter); builder.CloseElement(); diff --git a/src/Components/Components/test/RendererTest.cs b/src/Components/Components/test/RendererTest.cs index df713ec9d5..03d871c8ae 100644 --- a/src/Components/Components/test/RendererTest.cs +++ b/src/Components/Components/test/RendererTest.cs @@ -3655,7 +3655,6 @@ namespace Microsoft.AspNetCore.Components.Test protected override void BuildRenderTree(RenderTreeBuilder builder) { - base.BuildRenderTree(builder); var renderFactory = WhatToRender[TestId]; renderFactory(this)(builder); } diff --git a/src/Components/Components/test/Rendering/HtmlRendererTestBase.cs b/src/Components/Components/test/Rendering/HtmlRendererTestBase.cs index ff0836d627..38297e454b 100644 --- a/src/Components/Components/test/Rendering/HtmlRendererTestBase.cs +++ b/src/Components/Components/test/Rendering/HtmlRendererTestBase.cs @@ -482,7 +482,6 @@ namespace Microsoft.AspNetCore.Components.Rendering protected override void BuildRenderTree(RenderTreeBuilder builder) { - base.BuildRenderTree(builder); builder.OpenElement(0, "p"); builder.AddContent(1, Value.ToString()); builder.CloseElement(); @@ -513,7 +512,6 @@ namespace Microsoft.AspNetCore.Components.Rendering protected override void BuildRenderTree(RenderTreeBuilder builder) { - base.BuildRenderTree(builder); builder.OpenElement(0, "p"); builder.AddContent(1, Value.ToString()); builder.CloseElement();