dotnet icon indicating copy to clipboard operation
dotnet copied to clipboard

.NET Framework (WPF) Source Generators not working (when in same project)

Open jamesmontemagno opened this issue 2 years ago • 6 comments

1.) Create a new WPF Framework app and flip on C# 10 2.) Create a simple view model:

public partial class MainViewModel : ObservableObject
{
    public MainViewModel()
    {
    }

    [ObservableProperty]
    [AlsoNotifyChangeFor(nameof(FullName))]
    string firstName;


    [ObservableProperty]
    [AlsoNotifyChangeFor(nameof(FullName))]
    string lastName;


    public string FullName => $"{FirstName} {LastName}";


    [ICommand]
    async Task Submit()
    {
        Debug.WriteLine("DEBUG INFO: Submitted");
        this.FirstName = "test";
    }

}

The code will not compile and says that FirstName and LastName do not exist, even though there are no red squiggles and also the code is generated. The funny part is if you don't reference FirstName or LastName and only use firstName and lastName then the app will run and everything works...

Work around: Create a .NET Standard 2.0 library, flip on C# 10, and then move the ViewModel over there and it will work great.

See: https://github.com/jamesmontemagno/MVVMSourceGenerators/ for reference

jamesmontemagno avatar Mar 15 '22 18:03 jamesmontemagno

cc. @sharwell @BretJohnson this seems to be an issue with Roslyn or the WPF tooling, would you happen to have any more info on this, or maybe you know if this is already tracked somewhere else? If not, should we open an issue in another repo about this too? And, do you know if there are any other workarounds for this without going as far as creating a separate project? 😄

Thank you!

Sergio0694 avatar Mar 15 '22 18:03 Sergio0694

What's the exact error? @chsienki are there known cases where the source generator isn't passed to the XAML compiler?

sharwell avatar Mar 15 '22 19:03 sharwell

The errors are:

  • error CS0103: The name 'FirstName' does not exist in the current context
  • error CS1061: 'MainViewModel' does not contain a definition for 'FirstName' and no accessible extension method 'FirstName' accepting a first argument of type 'MainViewModel' could be found (are you missing a using directive or an assembly reference?)

What's interesting is, like you can see in the screenshot, these only show up in the output window, not in the errors list. Also, the IntelliSense does show the property, and I get no red squiggly line over it. What's more, the fields are also marked as unused though.

I can only repro this using the non-SDK style .csproj from the repo that James linked. I tried locally with an SDK-style project, and it works just fine both with .NET 6 and with .NET Framework 4.6.2.

So whatever this is, it does seem something with non-SDK style projects only 🤔 Does this help?

Sergio0694 avatar Mar 15 '22 19:03 Sergio0694

My guess is the WPF temp csproj that compiles the XAML isn't getting the correct (or any?) generators. We saw this problem when we first shipped generators, which was fixed. Its possible there is a different fix required for non-SDK projects. Will take a look and get back to you.

chsienki avatar Mar 15 '22 21:03 chsienki

@jamesmontemagno @Sergio0694 I looked into this, and its... not good news, as far as I can tell.

The 'legacy' style projects are targeting .NET Framework, which uses its own copy of the msbuild tasks (from the GAC) to do temporary project file generation. The newer open source WPF bits have been updated to support the passing of analyzers (https://cs.github.com/dotnet/wpf/blob/69a406c7f896042fba29a83943d58947cc8b11c3/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/Microsoft/Build/Tasks/Windows/GenerateTemporaryTargetAssembly.cs#L276), but when looking at source for the .NET FX bits it doesn't (MS Internal only: http://index/?leftProject=PresentationBuildTasks&leftSymbol=lgdczm99ssjn&file=Microsoft%5CBuild%5CTasks%5CWindows%5CGenerateTemporaryTargetAssembly.cs&line=98)

So you'll need servicing for the WPF bits inside .NET Framework itself to enable this scenario.

chsienki avatar Mar 21 '22 20:03 chsienki

@chsienki based on this, seems like what we need to do is update the docs when ready and say that it is supported through .NET Standard libraries

jamesmontemagno avatar Mar 21 '22 23:03 jamesmontemagno