dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.34k stars 4.74k forks source link

When compiling Blazor Hybrid app with NativeAOT, can't root System.Action generic #80075

Closed jaedan closed 1 year ago

jaedan commented 1 year ago

Description

I've built a simple WinForms application with a single BlazorWebView and I'm compiling it with NativeAOT. This repo contains code that reproduces the issue: https://github.com/jaedan/WinFormsBlazorHybridAOT/ (Additionally, I've repeated this same example using Photino instead of WinForms here: https://github.com/jaedan/Photino.Blazor.Native and I get the same result)

The applications compile and produce a binary. But when a razor page makes a call back to the main c# code (which triggers the message passing) then the application crashes because it is missing this type:

System.Action`2[Microsoft.AspNetCore.Components.Routing.Router, Microsoft.AspNetCore.Components.EventCallback`1[Microsoft.AspNetCore.Components.Routing.NavigationContext]]

I can't find any way to get that type into rd.xml that actually works. I've tried this:

<Assembly Name="System.Private.CoreLib">
  <Type Name="System.Action`2[Microsoft.AspNetCore.Components.Routing.Router, Microsoft.AspNetCore.Components.EventCallback`1[Microsoft.AspNetCore.Components.Routing.NavigationContext]]" Dynamic="Required All" />
</Assembly>

And that fails as follows:

 Failed to load type 'Microsoft.AspNetCore.Components.Routing.Router' from assembly 'System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'

I've changed the assembly name to Microsoft.AspNetCore.Components, but that just changes it so that it fails to load System.Action instead.

Reproduction Steps

To get crash notifying of missing runtime type:

To get rd.xml problems:

Expected behavior

Need to somehow root System.Action2[Microsoft.AspNetCore.Components, Microsoft.AspNetCore.Components.EventCallback1[Microsoft.AspNetCore.Components.Routing.NavigationContext]] so it stops getting trimmed.

Actual behavior

System.Action2[Microsoft.AspNetCore.Components, Microsoft.AspNetCore.Components.EventCallback1[Microsoft.AspNetCore.Components.Routing.NavigationContext]] gets trimmed

Regression?

I doubt anyone has ever tried this before.

Known Workarounds

Don't use NativeAOT

Configuration

Other information

Maybe this is related to #72833? It seems to me like it's trying to resolve the nested types within the parent assembly, but they're clearly in a different assembly so that behavior isn't correct. I'd love to be able to just root types more directly, without putting everything in an <Assembly> tag.

dotnet-issue-labeler[bot] commented 1 year ago

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

ghost commented 1 year ago

Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas See info in area-owners.md if you want to be subscribed.

Issue Details
### Description I've built a simple WinForms application with a single BlazorWebView and I'm compiling it with NativeAOT. This repo contains code that reproduces the issue: https://github.com/jaedan/WinFormsBlazorHybridAOT/ (Additionally, I've repeated this same example using Photino instead of WinForms here: https://github.com/jaedan/Photino.Blazor.Native and I get the same result) The applications compile and produce a binary. But when a razor page makes a call back to the main c# code (which triggers the message passing) then the application crashes because it is missing this type: ``` System.Action`2[Microsoft.AspNetCore.Components.Routing.Router, Microsoft.AspNetCore.Components.EventCallback`1[Microsoft.AspNetCore.Components.Routing.NavigationContext]] ``` I can't find any way to get that type into rd.xml that actually works. I've tried this: ``` ``` And that fails as follows: ``` Failed to load type 'Microsoft.AspNetCore.Components.Routing.Router' from assembly 'System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' ``` I've changed the assembly name to Microsoft.AspNetCore.Components, but that just changes it so that it fails to load System.Action instead. ### Reproduction Steps To get crash notifying of missing runtime type: - Clone https://github.com/jaedan/WinFormsBlazorHybridAOT/ - dotnet publish -r win-x64 --self-contained - Run executable To get rd.xml problems: - Modify rd.xml in the repo to add ``` ``` - dotnet publish -r win-x64 --self-contained ### Expected behavior Need to somehow root `System.Action`2[Microsoft.AspNetCore.Components, Microsoft.AspNetCore.Components.EventCallback`1[Microsoft.AspNetCore.Components.Routing.NavigationContext]]` so it stops getting trimmed. ### Actual behavior `System.Action`2[Microsoft.AspNetCore.Components, Microsoft.AspNetCore.Components.EventCallback`1[Microsoft.AspNetCore.Components.Routing.NavigationContext]]` gets trimmed ### Regression? I doubt anyone has ever tried this before. ### Known Workarounds Don't use NativeAOT ### Configuration - .net 7 - Win11 - x64 - Probably not specific to a configuration - It's WebView2, so Edge. ### Other information Maybe this is related to #72833? It seems to me like it's trying to resolve the nested types within the parent assembly, but they're clearly in a different assembly so that behavior isn't correct. I'd love to be able to just root types more directly, without putting everything in an `` tag.
Author: jaedan
Assignees: -
Labels: `untriaged`, `area-NativeAOT-coreclr`
Milestone: -
kant2002 commented 1 year ago

I think that's related to https://github.com/dotnet/aspnetcore/pull/45580 basically it's issue with how ASP.NET Core code is structure.

you have small issue in original rd.xml

<Assembly Name="System.Private.CoreLib">
  <Type Name="System.Action`2[[Microsoft.AspNetCore.Components.Routing.Router,Microsoft.AspNetCore.Components],[Microsoft.AspNetCore.Components.EventCallback`1[[Microsoft.AspNetCore.Components.Routing.NavigationContext,Microsoft.AspNetCore.Components]],Microsoft.AspNetCore.Components]]" Dynamic="Required All" />
</Assembly>

Notice that because Microsoft.AspNetCore.Components.Routing.Router is in different assembly then System.Private.CoreLib, you need specify assembly name when reference type name. Don't forget wrap in []. So

before

Microsoft.AspNetCore.Components.Routing.Router

after

[Microsoft.AspNetCore.Components.Routing.Router, Microsoft.AspNetCore.Components]

I think you can simplify rd.xml by just writing declaration like this

<Assembly Name="Microsoft.AspNetCore.Components">
  <Type Name="Microsoft.AspNetCore.Components.Routing.Router" Dynamic="Required All" />
  <Type Name="Microsoft.AspNetCore.Components.EventCallback`1[Microsoft.AspNetCore.Components.Routing.NavigationContext]]" Dynamic="Required All" />
</Assembly>

it's quite possible that you need to root just one class, because others are already detected. I can only recommend guessing here.

jaedan commented 1 year ago

Ok, I understand now how to get the rd.xml to find the types and that seems to be working. It doesn't fix the problems - I still get errors that MethodInfo.MakeGenericMethod() is not compatible with AOT compilation, and this must be related to the issue you posted. I think we can close this one and just track it in that issue instead.

Thanks for the help!