The Wayback Machine - https://web.archive.org/web/20220113190144/https://github.com/dotnet/aspnetcore/issues/39494
Skip to content
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

Add support for Blazor Component Extension like C# code extension #39494

Open
sake402 opened this issue Jan 13, 2022 · 0 comments
Open

Add support for Blazor Component Extension like C# code extension #39494

sake402 opened this issue Jan 13, 2022 · 0 comments

Comments

@sake402
Copy link

@sake402 sake402 commented Jan 13, 2022

Is your feature request related to a problem? Please describe.

The main purpose of extension code in C# is so we can add methods/operations to an object without adding the member to the class itself.
In Blazor however, in order to reuse a piece of UI code, you have to wrap it into a component or use an C# extension as below

RenderFragment GetButton(this ComponentBase caller, ButtonType buttonType, Theme buttonTheme)
{
    return (builder) =>
    {

    };
}

This method can then be called from any component as

@this.GetButton(ButtonType.Icon, Theme.Primary)

Component creation however can be costly in terms of performance as blazor has to manage and maintain the state of the components.
However some components can be very basic in terms of functionalities, for example a Button Component simply wraps <button> and a couple of ifs.
A grid cell component is just a td

Describe the solution you'd like

What is proposed is that such basic component should be expressable as an extension method in .razor file or .cs file that returns RenderFragment and takes a number of parameter that would rather be decorated with [Parameter] in the component.

public static class ComponentExtension
{
    //user must supply all parameters except optional ones which are optional
    //Extension component name must start with a Get and returns RenderFragment
    //Can have parameters and even optional ones
	
	//this component can be used from any component
    public static RenderFragment GetButton(this ComponentBase callerComponent, ButtonType buttonType, Theme buttonTheme, EventCallback click, int optionalParameter = 0)
    {
        return @<button @onclick="click" class="@buttonType @buttonTheme"></button>;
    }

	//this component can be used from any component
    public static RenderFragment GetButton2(this ComponentBase callerComponent, ButtonType buttonType, Theme buttonTheme, EventCallback click, int optionalParameter = 0)
    {
        return (builder) => 
        {
             builder.OpenElement("button");
             //more builders
             builder.CloseElement();
        }
    }
	
	//this component can be used only in CardComponent or super classes
	public static RenderFragment GetButton3(this CardComponent callerComponent, ButtonType buttonType, Theme buttonTheme, EventCallback click, int optionalParameter = 0)
    {
        return (builder) => 
        {
             builder.OpenElement("button");
             //more builders
             builder.CloseElement();
        }
    }
	
	//this component can be used only in super classes of MyBaseComponent
	public static RenderFragment GetButton4<TComponent>(this CardComponent callerComponent, ButtonType buttonType, Theme buttonTheme, EventCallback click, int optionalParameter = 0) where TComponent : MyBaseComponent
    {
        return (builder) => 
        {
             builder.OpenElement("button");
             //more builders
             builder.CloseElement();
        }
    }
}

The razor generator will however allow this Component Extensions to be referenced like a normal component as

<Button ButtonType="ButtonType.Icon" ButtonTheme="Theme.Primary" Click="DoSomething"></Button>
<Button2 ButtonType="ButtonType.Icon" ButtonTheme="Theme.Primary" Click="DoSomething"></Button2>

and will generate a call to the extension method

builder.AddContent(1, this.GetButton(ButtonTyp.Icon, Theme.Primary, EventCallback.Factory.Create(this, DoSomething)));

Additional context

The advantage of this majorly is that the numbers of such component created will not have drawback on performance as it is simply a method call while user still get a feel of razor syntax instead of C# code in razor file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
1 participant