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

WPF XAML file can't see types generated by Razor Source Generator #4421

Closed
Eilon opened this issue Apr 16, 2021 · 3 comments · Fixed by #6535
Closed

WPF XAML file can't see types generated by Razor Source Generator #4421

Eilon opened this issue Apr 16, 2021 · 3 comments · Fixed by #6535
Assignees
Labels

Comments

@Eilon
Copy link
Member

Eilon commented Apr 16, 2021

  • .NET Core Version: 6.0-preview3
  • Windows version: N/A
  • Does the bug reproduce also in WPF for .NET Framework 4.8?: N/A
  • Is this bug related specifically to tooling in Visual Studio? No (interestingly, this does work in VS IntelliSense, but not when compiling!)

Problem description:

In .NET 6 we are enabling authoring of WPF apps in a "Blazor Desktop" scenario where Blazor web UI (HTML+CSS) is hosted in a web view in a WPF app. Such projects contain a mix of XAML (WPF), Blazor/Razor (HTML+CSS), and other code artifacts (C#, etc.). This is done with a new <BlazorWebView ... /> WPF control being built by the ASP.NET team.

The XAML compiler, however, is unable to see the types generated by the Razor Source Generator. (Note: Using a source generator is new for Blazor in .NET 6; previously it was done in other ways).

For the WPF BlazorWebView control we’d like to support a XAML syntax like this to specify a Razor component to load:

<Window ...
        xmlns:local="clr-namespace:BlazorWpfApp">
   <DockPanel>
        ...
        <blazor:BlazorWebView HostPage="wwwroot\index.html" Services="{StaticResource services}">
            <blazor:BlazorWebView.RootComponents>
                <blazor:RootComponent Selector="#app" ComponentType="{x:Type local:Main}" />
            </blazor:BlazorWebView.RootComponents>
        </blazor:BlazorWebView>
    </DockPanel>
</Window>

Where local:Main is a class that is generated by the Razor compiler as part of the project’s compilation. There is a file Main.razor that generates a type Main in the same namespace. The Razor-generated class is visible from C# code, but the XAML compiler is unable to find.

From @captainsafia in an email thread:

We'll need to do some work on the WPF size to react to the changes made in the Razor SDK.

Actual behavior:

In VS Intellisense you can see the Razor-generated types (good):
image

But when you try to compile the app, the XAML compiler can't see the same type anymore (bad):

...\MainWindow.xaml(17,55): error MC3050: Cannot find the type 'local:Main'. Note that type names are case sensitive. Line 17 Position 55.

Expected behavior:

The XAML compiler should be able to see the Razor generated types and compile.

Minimal repro:

See repro app here: https://github.com/Eilon/WPFXamlRazorGeneratorBug

To see just the relevant code, look at this commit: Eilon/WPFXamlRazorGeneratorBug@b500285

  1. Open the SLN in VS
  2. Try to run the app, you get the above-mentioned XAML compiler error
  3. In MainWindow.xaml.cs un-comment the line at the bottom of the file
  4. Then everything works fine

Workarounds:

There are workarounds for this issue:

  1. In the WPF app create a partial class with the same name as the Razor-generated type. The types in Razor are all partial too, so this doesn't really create a new type, but it enables the XAML compiler to believe the type it exists, while creating no ill effects. For example partial class Index {}.
  2. Move all the Razor files (*.razor) to a Razor Class Library so that all the Razor-generated types are available prior to the XAML compiler running, thus enabling it to "see" all the types.

cc @captainsafia @danroth27

@captainsafia
Copy link
Member

Some more helpful info from the email thread:

It looks like you might be running into some issues related to a breaking change that we made recently in the Razor compiler (see aspnet/Announcements#459).

Previously, the Razor compiler produced a separate AppName.Views.dll assembly that contained the compiled view types in an application as public​ classes under the AspNetCore​namespace.

Now, the Razor compiler produces a single AppName.dll that contains the compiled view types as internal sealed​ classes under the AspNetCoreGenerated​ namespace.

My hunch is that this change is causing the problem that you see here. It's likely that your implementation will work in .NET 6 Preview 2 and earlier.

Our current model of compiling the views into a single assembly as internal​ types is in place to support some build improvements and hot reload so we'll need to sort out a solution for this moving forward.

@taoyouh
Copy link

taoyouh commented Aug 20, 2021

Actually WPF XAML cannot see types generated by other "source generators" too. For example, the resource designer classes generated by VocaDb.ResXFileCodeGenerator cannot be used in WPF XAML file.

@ThomasGoulet73
Copy link
Contributor

I opened #6535 which should fix the issue.

A temporary workaround would be to add <RootNamespace>WpfBlazorRepro</RootNamespace> to the csproj.

@ThomasGoulet73 ThomasGoulet73 added the Bug Product bug (most likely) label May 5, 2022
@ThomasGoulet73 ThomasGoulet73 self-assigned this May 5, 2022
ThomasGoulet73 added a commit to ThomasGoulet73/wpf that referenced this issue Aug 1, 2023
@ghost ghost removed the 🚧 work in progress label Aug 21, 2023
@ghost ghost removed this from the 7.0.0 milestone Aug 21, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Sep 20, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants