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

Make Blazor More Extensible #55853

Closed
codymullins opened this issue May 23, 2024 · 4 comments
Closed

Make Blazor More Extensible #55853

codymullins opened this issue May 23, 2024 · 4 comments
Labels
area-blazor Includes: Blazor, Razor Components design-proposal This issue represents a design proposal for a different issue, linked in the description ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. question Status: Resolved

Comments

@codymullins
Copy link

codymullins commented May 23, 2024

Summary

Many built-in components and services for Blazor are internal or are marked as public sealed, which is frustrating when trying to extend Blazor. For example, while Router is public, RouteData is sealed and cannot be extended. Similarly, both SectionOutlet and SectionContent are sealed.

There are many more if you search public sealed in the components folder.

I would like to propose:

  1. We review components that are sealed and unseal them, unless there is a very strong reason to leave them sealed.
  2. New features should be public and unsealed, so that they can be easily extended. The default should not be to seal things, IMO.
  3. I am open to alternative strategies, but the theme I am pushing here is making it easier to extend Blazor.

We love Blazor and want to help continue pushing it forward.

Motivation and goals

  • Extending default behaviors can be frustrating - for example, instead of simply extending SectionOutlet to add more functionality, it must now be composed in a new component.
  • Our CMS provides special authentication rules out of the box: we cannot extend the existing AuthorizeRouteView as it is sealed. Instead, we have to either copy the existing code into our class or somehow compose it in another layer.
  • Our CMS also injects metadata into pages - with many of the underlying components either public sealed or internal, we end up "stubbing our toe" on things that shouldn't be that complicated. Lots of annoying quirks around Routing and <HeadContent> or the <PageTitle>.

In scope

  • Open up the core components to be extensible (e.g. HeadContent, TitleContent, SectionOutlet, etc)

Out of scope

Wishlist: Open up the Router for better extensibility, and consider implementing a v2 router with less ties to Shared resources in other packages. (probably a separate issue, but related to extensibility)

Risks / unknowns

  • Certain components, perhaps related to Auth, might understandably need to remain sealed.
  • Issue triage in the future may need to consider if a 3p extension is causing the problem. However, with issue repros, this may be a non-issue
  • 3p extensions could cause issues for users, but that should be left up to the consumer

Examples

Give brief examples of possible developer experiences (e.g., code they would write).

Crazy sample (psuedocode-ish) to demonstrate:

public class OptionalRemoteSectionOutlet : SectionOutlet 
{
   // pseudocode
   BuildRenderTree(builder)
   {
      if (component is not null) 
      {
         render(component);
      }
      else 
      { 
         RenderFragment fragment = remoteFragmentClient.DownloadRemoteComponent(""); 
         render(fragment);
      }
}
@codymullins codymullins added the design-proposal This issue represents a design proposal for a different issue, linked in the description label May 23, 2024
@dotnet-issue-labeler dotnet-issue-labeler bot added the area-blazor Includes: Blazor, Razor Components label May 23, 2024
@javiercn
Copy link
Member

@codymullins thanks for contacting us.

In general, we do not make anything that we don't have a clear use case for public or virtual. Anything that we make public or virtual in that situation adds risk as it precludes us in the future from making changes.

We are open to making more things public / virtual and in general, adding additional extensibility points, when there are clear use cases and demand for them, but having an "extensible by default" policy adds a lot of risk to evolve the framework in the future without breaking existing users inadvertedly.

If you have concrete asks, please file separate issues with the concrete scenarios and asks for us to consider.

@javiercn javiercn added question ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. labels May 23, 2024
@codymullins
Copy link
Author

as it precludes us in the future from making changes

Well, it doesn't. There are breaking changes all the time in .NET, I don't think Blazor should be treated any differently.

when there are clear use cases and demand for them ... adds a lot of risk to evolve the framework in the future

Innovation gets stifled this way. Having a more extensible, open model I believe would allow more innovation from the community, not just what gets approved by the .NET team.

JavaScript doesn't have "internal" or "sealed" things and UI frameworks built for the JS community has more innovation outside of the maintainer - you can replace things, upgrade them, enhance them.

Please, for the sake of the future of Blazor and growing usage, consider having things less locked down.

@codymullins
Copy link
Author

Seems like there is support for more innovation in the Blazor space at the risk of breaking changes: https://x.com/codemullins/status/1793691901771575784

image

@danroth27 - can we discuss this a bit more?

@gragra33
Copy link

@codymullins There is a new feature coming to C# 13 that will address this for you. Watch this video from @Elfocrash The New Extensions EVERYTHING Feature of C# 13!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-blazor Includes: Blazor, Razor Components design-proposal This issue represents a design proposal for a different issue, linked in the description ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. question Status: Resolved
Projects
None yet
Development

No branches or pull requests

3 participants