Skip to content

Proposal: Allow base component classes to augment the generated BuildRenderTree output #12350

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
PaloMraz opened this issue Jul 19, 2019 · 2 comments
Labels
area-blazor Includes: Blazor, Razor Components enhancement This issue represents an ask for new feature or an enhancement to an existing one
Milestone

Comments

@PaloMraz
Copy link

Please note: This is related to #9857 but that is already closed, therefore a new proposal...

I am trying to add common functionality to a hierarchy of components by overriding the BuildRenderTree method in a common base class like this:

StyledComponentBase.cs

public abstract class StyledComponentBase : ComponentBase
{
    protected StyledComponentBase()
    {
    }

    public string BackgroundColor { get; set; } = "yellow";

    public string Style => $"background-color: {this.BackgroundColor};";

    protected override void BuildRenderTree(RenderTreeBuilder builder)
    {
        base.BuildRenderTree(builder);

        builder.OpenElement(0, "div");
        builder.AddAttribute(1, "style", this.Style);
        builder.AddContent(2, $"Added by {this.GetType().Name}");
        builder.CloseElement();
    }
}

StyledParentComponent.razor

@inherits  StyledComponentBase

<h3>StyledParentComponent</h3>

@code {

}

But this scenario does not work, because the generated StyledParentComponent class' overriden BuildRenderTree method does not call the base class (as noted in #9857):

obj\Debug\netstandard2.0\Razor\Components\StyledParentComponent.razor.g.cs

public class StyledParentComponent : StyledComponentBase
{
    #pragma warning disable 1998
    protected override void BuildRenderTree(Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder)
    {
        builder.AddMarkupContent(0, "<h3>StyledParentComponent</h3>");
    }
    #pragma warning restore 1998
}

It would be very useful IMHO, to add the possibility for base component classes to somehow augment the markup produced by derived classes generated from .razor files. For example ComponentBase could introduce two new virtual methods:

/// <summary>
/// In generated code, call to this method is inserted before the generated BuildRenderTree call.
/// </summary>
protected virtual void AugmentRenderTreeBeforeGeneratedContent(RenderTreeBuilder builder)
{
}

/// <summary>
/// In generated code, call to this method is inserted after the generated BuildRenderTree call.
/// </summary>
protected virtual void AugmentRenderTreeAfterGeneratedContent(RenderTreeBuilder builder)
{
}

And the .razor compiler would include calls to the methods in the generated code like this:

public class StyledParentComponent : StyledComponentBase
{
    #pragma warning disable 1998
    protected override void BuildRenderTree(Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder)
    {
        this.AugmentRenderTreeBeforeGeneratedContent(builder);
        builder.AddMarkupContent(0, "<h3>StyledParentComponent</h3>");
        this.AugmentRenderTreeAfterGeneratedContent(builder);
    }
    #pragma warning restore 1998
}
@mkArtakMSFT mkArtakMSFT added area-blazor Includes: Blazor, Razor Components enhancement This issue represents an ask for new feature or an enhancement to an existing one PRI: 2 - Preferred labels Jul 19, 2019
@mkArtakMSFT mkArtakMSFT added this to the Backlog milestone Jul 19, 2019
@mkArtakMSFT
Copy link
Contributor

We've moved this issue to the Backlog milestone. This means that it is not going to happen for the coming release. We will reassess the backlog following the current release and consider this item at that time. However, keep in mind that there are many other high priority features with which it will be competing for resources.

@SteveSandersonMS
Copy link
Member

Thanks for the suggestion!

This is not something we're specifically planning to do because (1) it's not something that's attracted a lot of community interest in the last year, and (2) inheritance is not the best form of extensibility we'd recommend - the component programming model is oriented around composition rather than inheritance when it comes to wrapping components inside each other.

@ghost ghost locked as resolved and limited conversation to collaborators Nov 13, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components enhancement This issue represents an ask for new feature or an enhancement to an existing one
Projects
None yet
Development

No branches or pull requests

4 participants