AspNetCore.Docs icon indicating copy to clipboard operation
AspNetCore.Docs copied to clipboard

Is using __builder in the examples a good idea?

Open SQL-MisterMagoo opened this issue 3 years ago • 3 comments

In the section Define reusable RenderFragments in code, the RenderFragment is defined using __builder and the comments state that it "must be called __builder" - which, I believe is because the RenderTreeBuilder instance used by the Razor compiler for a component happens to be called __builder and this happens to make the declaration work.

private RenderFragment RenderWelcomeInfo = __builder =>
  {
      <p>Welcome to your new app!</p>
  };

This seems like a curious thing to put in the docs, when the name "__builder" is not part of a public API and could change at some point in the future.

The sample could be re-written without this restriction as

public static RenderFragment RenderWelcomeInfo = 
  @<p>Welcome to your new app!</p>;

Or, for a more complicated markup fragment as

public static RenderFragment RenderWelcomeInfo = 
  @<text>
        <h2>Welcome to your new app!</h2>
        <p>It's the future!</p>
   </text>;

So, my question is - should the docs at least show an alternative such as the ones above - or even replace the __builder version?

Opinion My personal preference, having just had someone tell the chat that "it has to use __builder" because of this doc, would be to change the sample to the @<text> version. I find it easier to read as well as not relying on an internal name.


Document Details

Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

SQL-MisterMagoo avatar May 09 '22 16:05 SQL-MisterMagoo

Hello @SQL-MisterMagoo ...

The RenderFragment delegate must accept a parameter called __builder of type RenderTreeBuilder so that the Razor compiler can produce rendering instructions for the fragment.

The product unit supplied the content on this subject. There's likely a bit more to the story on that remark. Unless the 🧀 moved in the framework since the content was written (it has been up quite a while ... a couple of years I think), the product unit wouldn't normally use language like "must accept" unless that was important to avoid arbitrary behavior, security problems, perf problems, etc. — OR — this is a qualified scenario that only applies to one (or a few) specific render fragment scenarios.

I'll ping to have them look at this, but I need to prioritize this for June (or even a little later) due to the big push on Blazor Hybrid's rollout. It won't get lost tho ... I'll make sure that we get an answer on it.

Also, I agree with you that it should be documented one way or the other. If your alternatives are fine for "create reusable rendering logic without implementing additional components," great ... let's cross-link current content (or add coverage here, if appropriate). If there's a reason not to use those alternatives because this is a special case of "create reusable rendering logic without implementing additional components," then this guidance should state the scenario and qualification for the guidance more clearly.

I'll cross-link our Razor template remarks with RenderFragment for visibility here. Your alternatives are in that vein ...

https://docs.microsoft.com/aspnet/core/blazor/components/#razor-templates

They appear in a few other spots, too ... child content ... overwritten params coverage ... the templated components topic ... and in other assorted spots, usually examples that demo other concepts.

guardrex avatar May 09 '22 16:05 guardrex

UPDATE (7/15): I'll ask management again about this today.

guardrex avatar Jul 15 '22 12:07 guardrex

UPDATE (8/11): Very sorry for the delay! There's a delay due to the work for the upcoming .NET 7 release. We'll get to this ASAP, but I don't have an ETA. I'll remind them tomorrow, Friday, about your issue.

guardrex avatar Aug 11 '22 14:08 guardrex

UPDATE (8/29): I'm checking now to see if Steve has a sec to look at this. We might be able to find out quickly if your proposal should be pursued. We might work this later in the year tho. Let's see if he has time to look 🏃😅.

guardrex avatar Aug 29 '22 13:08 guardrex

@guardrex Yes, I agree with @SQL-MisterMagoo's suggestion here. It would be better to use the simplified syntax without __builder. I suspect that some older version of the Razor compiler might not have supported that, but it does work well with the current Razor compiler.

That is,

public static RenderFragment SayHello = @<h1>Hello!</h1>;

... and:

@code {
    private RenderFragment<ChatMessage> ChatMessageDisplay = message =>
        @<div class="chat-message">
            <span class="author">@message.Author</span>
            <span class="text">@message.Text</span>
        </div>;
}

...and:

protected RenderFragment DisplayTitle =>
    @<div>
        @TitleTemplate
    </div>;

As far as versioning is concerned, this approach can be documented for .NET 6+. We don't have an equivalent section in the docs for 5.x or earlier so don't need to check it for that.

SteveSandersonMS avatar Sep 01 '22 12:09 SteveSandersonMS

Thanks @SteveSandersonMS ... I'll take care of this quickly. 🏃

guardrex avatar Sep 01 '22 12:09 guardrex