dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.51k stars 10.04k forks source link

BlazorWebView needs a way to enable overriding ResolveComponentForRenderMode #51235

Open Eilon opened 1 year ago

Eilon commented 1 year ago

Scenario: I have Razor components enabled for various interactivity modes in a Blazor web app, such as specifying @attribute [RenderModeInteractiveServer]. I want to place those components in a Razor Class Library (RCL) and re-use them in a Blazor Hybrid app.

Problem: You get errors stating that the interactivity modes are not supported in BlazorWebView's hybrid renderer.

@eilon said in a chat:

I can confirm that pages with @attribute [RenderModeInteractiveServer] make Blazor Hybrid sad

@SteveSandersonMS responded:

... Blazor Hybrid's renderer could override ResolveComponentForRenderMode and implement any behavior it wants around resolving rendermodes. The default in the Renderer base class is to throw because it doesn't know what rendermodes would make sense in what cases. But we could say (for example) that InteractiveServer and InteractiveAuto modes should be allowed on Blazor Hybrid and would just be no-ops, because it's already interactive. To do that, the renderer subclass would override ResolveComponentForRenderMode and just return componentActivator.CreateInstance(componentType), so that no rendermode-specific behavior is introduced.

It would still be a bit odd that InteractiveServer or InteractiveWebAssembly would have any meaning for webview. It would sort of make sense if they somehow did use a server or WebAssembly. The fact that they don't is why we didn't think it was right to do this in .NET 8. Maybe we need to reopen the question of having a mode simply called Interactive that for web would require you to configure globally how you want it to be resolved, whereas for WebView would be a no-op.

Enabling this requires some change in the aspnetcore repo, such as:

  1. Just changing WebViewRenderer to do this directly. BlazorWebView has no access to the renderer because it's privately created in the core types here: https://github.com/dotnet/aspnetcore/blob/c84bdf4782142fbfd14d032cec3c2f2a07566274/src/Components/WebView/WebView/src/PageContext.cs#L49)
  2. Adding some extensibility to enable the change to be made in BlazorWebView and its associated classes

Note: Customers have also noticed this: https://github.com/dotnet/maui/issues/17725

ghost commented 1 year ago

Thanks for contacting us.

We're moving this issue to the .NET 9 Planning milestone for future evaluation / consideration. We would like to keep this around to collect more feedback, which can help us with prioritizing this work. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

chulla commented 1 year ago

i think this issu is relationed : https://github.com/dotnet/aspnetcore/issues/52129

ghost commented 10 months ago

Thanks for contacting us.

We're moving this issue to the .NET 9 Planning milestone for future evaluation / consideration. We would like to keep this around to collect more feedback, which can help us with prioritizing this work. We will re-evaluate this issue, during our next planning meeting(s). If we later determine, that the issue has no community involvement, or it's very rare and low-impact issue, we will close it - so that the team can focus on more important and high impact issues. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

Eilon commented 9 months ago

For anyone wanting to try a workaround that should work in any .NET 8 Blazor app (Blazor Web or Blazor Hybrid), check out the sample PR here: https://github.com/BethMassi/HybridSharedUI/pull/1

In the sample there are a few parts to note:

  1. The shared Razor Class Library (RCL) has a new global static property used to configure what render mode should be used for components that need to specify their own render mode: https://github.com/BethMassi/HybridSharedUI/pull/1/files#diff-d4a32ec54df005ebfc942314c38a1ffae962e4b0f0431334d20869d4543c4f54R5
  2. Any component in the RCL that wants to use a render mode should use that global static value, for example in Counter.razor: https://github.com/BethMassi/HybridSharedUI/pull/1/files#diff-6d3252583e54439ec4f502142bc6bbd18fd2b7aa66eb0aba093af304c22c9358R2
  3. The Blazor Web app sets the global static to the desired value: https://github.com/BethMassi/HybridSharedUI/pull/1/files#diff-5aaf282c84c804227c5da8e4bcaa06b881ba7634013aa0db927ae16a70b5cd97R6
  4. The Blazor Hybrid (MAUI) app doesn't set the value because all components are always interactive here

Note: This won't help you if you don't own all the code that sets the render modes. For example, a 3rd party NuGet package that already sets a render mode will not work in a Blazor Hybrid app.