dotnet icon indicating copy to clipboard operation
dotnet copied to clipboard

.net 4.7.2 Accessing properties causing compilation error

Open chocobot opened this issue 2 years ago • 16 comments

Describe the bug

public partial class MainViewModel : ObservableObject
{
    [ObservableProperty]
    public string _title = "Window Name";


    [ObservableProperty] 
    public string _buttonCaption = "This is a button";


    [RelayCommand(CanExecute = nameof(CanRunTestButton))]
    public void RunTestButton()
    {
        Title = "The window name has changed";
    }

    public bool CanRunTestButton()
    {
        return Title == "Window Name";
    }     
}

When running this example, I am getting a compile error stating

Rebuild started... 1>------ Rebuild All started: Project: LearningFramework, Configuration: Debug Any CPU ------ Restored C:\Users\iifuz\source\repos\LearningFramework\LearningFramework\LearningFramework.csproj (in 10 ms). 1>C:\Users\iifuz\source\repos\LearningFramework\LearningFramework\Windows\Main\MainViewModel.cs(26,13,26,18): error CS0103: The name 'Title' does not exist in the current context 1>C:\Users\iifuz\source\repos\LearningFramework\LearningFramework\Windows\Main\MainViewModel.cs(31,20,31,25): error CS0103: The name 'Title' does not exist in the current context ========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ========== ========== Rebuild started at 7:58 AM and took 00.578 seconds ==========

Without accessing the Title property, data binding is working fine in the XAML.

I did see a separate closed issue on this github regarding a IncludePackageReferencesDuringMarkupCompilation property to set within the csproj, however this is not available in 4.7.2 from what I can tell?

Steps to reproduce

Compile the code in the description.

Expected behavior

That the code compiles and binds accordingly.

Visual Studio Version

2022

Help us help you

Yes, I'd like to be assigned to work on this item.

chocobot avatar Mar 11 '23 13:03 chocobot

Hello chocobot, thank you for opening an issue with us!

I have automatically added a "needs triage" label to help get things started. Our team will analyze and investigate the issue, and escalate it to the relevant team if possible. Other community members may also look into the issue and provide feedback 🙌

ghost avatar Mar 11 '23 13:03 ghost

Hey @chocobot, are you using packages.config by any chance? Or did you reference the MVVM Toolkit through PackageReference?

Sergio0694 avatar Mar 13 '23 23:03 Sergio0694

Yes I did, I switched to package reference and switched the c# version to 11 in the csproj..

I can databind the Title property to the window title in the XAML I can bind the button command and it triggers properly..

However, as soon as I try to reference the Title property within the view model, nothing will compile.

chocobot avatar Mar 15 '23 01:03 chocobot

Is this using the MVVM Toolkit 8.1? Does it also repro with 8.0?

Sergio0694 avatar Mar 18 '23 13:03 Sergio0694

Hey @chocobot, friendly ping, we need your feedback to be able to properly triage this 🙂 Are you never able to compile when directly referencing those properties in code? What version of VS are you using? And is this with the MVVM Toolkit 8.0 or 8.1? If with the 8.1, do you also repro the same issue if you try going back to 8.0?

Thank you! 🙂

Sergio0694 avatar Mar 25 '23 01:03 Sergio0694

I am using the latest version 8.1.0 and I have also encountered this problem. Is there a solution? @Sergio0694

iBoundary avatar Apr 06 '23 04:04 iBoundary

@Sergio0694 I'm having the same problem myself with all versions actually 7.1.2, 8.0.0, 8.1.0 and 8.2.0. I tried 4.8 and 4.7.2 also but without success. The wired thing is that accessing a generated property will only cause the build to fail if the generation happens in the WPF project, if it's in a class library (4.8) it won't cause any problems and you can access it in both the class library and the WPF project referencing it.

@iBoundary @chocobot might be a workaround for you.

akarboush avatar May 31 '23 12:05 akarboush

Here is a minimal reproducible solution. https://github.com/MH-ZShearer/SourceGeneratorTest

The same exact code in a .NET 7.0 application works, but this .NET Framework 4.8 fails to compile with:

error CS0103: The name 'TestCommand' does not exist in the current context

I have tried v8.0, v8.1, and v8.2 and all of them provide the same issue. I am currently using VS v17.6.3.

It is worth noting that the generators are generating the expected code and the application works as expected, but only if there are no references in C# to the generated properties or commands. In this case, if we replace nameof(TestCommand) with the string literal "TestCommand", the application compiles as expected, but this is an unsustainable workaround.

MH-ZShearer avatar Jun 14 '23 18:06 MH-ZShearer

@Sergio0694 I'm having the same problem myself with all versions actually 7.1.2, 8.0.0, 8.1.0 and 8.2.0. I tried 4.8 and 4.7.2 also but without success. The wired thing is that accessing a generated property will only cause the build to fail if the generation happens in the WPF project, if it's in a class library (4.8) it won't cause any problems and you can access it in both the class library and the WPF project referencing it.

@iBoundary @chocobot might be a workaround for you.

add <IncludePackageReferencesDuringMarkupCompilation>true</IncludePackageReferencesDuringMarkupCompilation> into your PropertyGroup like this

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net472</TargetFramework>
    <UseWPF>true</UseWPF>
    <IncludePackageReferencesDuringMarkupCompilation>true</IncludePackageReferencesDuringMarkupCompilation>
  </PropertyGroup>

VergilGao avatar Jun 29 '23 01:06 VergilGao

Here is a minimal reproducible solution. https://github.com/MH-ZShearer/SourceGeneratorTest

The same exact code in a .NET 7.0 application works, but this .NET Framework 4.8 fails to compile with:

error CS0103: The name 'TestCommand' does not exist in the current context

I have tried v8.0, v8.1, and v8.2 and all of them provide the same issue. I am currently using VS v17.6.3.

It is worth noting that the generators are generating the expected code and the application works as expected, but only if there are no references in C# to the generated properties or commands. In this case, if we replace nameof(TestCommand) with the string literal "TestCommand", the application compiles as expected, but this is an unsustainable workaround.

This is because you used the old csproj file when building the netFramework project, and the easiest way to build the project is to build a net7 project first, and then manually modify the .csproj file to change 'TargetFramework' to net48

VergilGao avatar Jun 29 '23 01:06 VergilGao

add <IncludePackageReferencesDuringMarkupCompilation>true</IncludePackageReferencesDuringMarkupCompilation> into your PropertyGroup like this

  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net472</TargetFramework>
    <UseWPF>true</UseWPF>
    <IncludePackageReferencesDuringMarkupCompilation>true</IncludePackageReferencesDuringMarkupCompilation>
  </PropertyGroup>

~~Appreciate it @VergilGao . It works~~

Edit: no It's not working. It could be that I tried with an another project, not sure how.

It seems like the IncludePackageReferencesDuringMarkupCompilation is completely ignored in the GenerateTemporaryTargetAssembly - where the problem occurs according to the binlog file - target task

C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Microsoft.WinFx.targets (used in .net 48)

 <GenerateTemporaryTargetAssembly
          CurrentProject="$(MSBuildProjectFullPath)"
          MSBuildBinPath="$(MSBuildBinPath)"
          ReferencePathTypeName="ReferencePath"
          CompileTypeName="Compile"
          GeneratedCodeFiles="@(_GeneratedCodeFiles)"
          ReferencePath="@(ReferencePath)"
          IntermediateOutputPath="$(IntermediateOutputPath)"
          AssemblyName="$(AssemblyName)"
          CompileTargetName="$(_CompileTargetNameForLocalType)"
          GenerateTemporaryTargetAssemblyDebuggingInformation="$(GenerateTemporaryTargetAssemblyDebuggingInformation)"
                 >

the corresponding for .net 7

 <GenerateTemporaryTargetAssembly
                CurrentProject="$(MSBuildProjectFullPath)"
                MSBuildBinPath="$(MSBuildBinPath)"
                ReferencePathTypeName="ReferencePath"
                CompileTypeName="Compile"
                AnalyzerTypeName="Analyzer"
                GeneratedCodeFiles="@(_GeneratedCodeFiles)"
                ReferencePath="@(ReferencePath)"
                BaseIntermediateOutputPath="$(BaseIntermediateOutputPath)"
                IntermediateOutputPath="$(_IntermediateOutputPathNoTargetFrameworkOrRID)"
                AssemblyName="$(AssemblyName)"
                CompileTargetName="$(_CompileTargetNameForLocalType)"
                GenerateTemporaryTargetAssemblyDebuggingInformation="$(GenerateTemporaryTargetAssemblyDebuggingInformation)"
                IncludePackageReferencesDuringMarkupCompilation="$(IncludePackageReferencesDuringMarkupCompilation)"
                Analyzers="@(Analyzer)"
                TemporaryTargetAssemblyProjectName="$(_TemporaryTargetAssemblyProjectName)"
                MSBuildProjectExtensionsPath="$(MSBuildProjectExtensionsPath)"
                 >

akarboush avatar Jun 29 '23 09:06 akarboush

This is because you used the old csproj file when building the netFramework project, and the easiest way to build the project is to build a net7 project first, and then manually modify the .csproj file to change 'TargetFramework' to net48

@VergilGao while that works for this scenario, it does not work for our monolithic legacy application. The SDK style csproj format for .NET Framework 4.8 does not support ClickOnce, for example. I did verify this solution works for new projects, however, but it cannot be used to retrofit legacy applications.

If you have any other suggestions, I'd be glad to give it a go.

MH-ZShearer avatar Jun 29 '23 19:06 MH-ZShearer

Adding <IncludePackageReferencesDuringMarkupCompilation>true</IncludePackageReferencesDuringMarkupCompilation> results in new errors due to the task GenerateTemporaryTargetAssembly being executed. This particular task was responsible for creating the *_wpftmp.csproj.

It seems that these temporary assemblies, project names, or what-have-you were also perhaps in part responsible for failure to resolve types defined in the same assembly.

Apparently, this setting defaulted to false in .NET 5.0, however that is no longer the case in .NET 6.0. Indeed, it is on by default, and it would appear that this option, when enabled, is what is responsible for generating all those temporary assemblies and causing resolution errors as well warnings due to underscores in the file names of these temporary assemblies.

Adding <IncludePackageReferencesDuringMarkupCompilation>true</IncludePackageReferencesDuringMarkupCompilation> does not really resolve the issue.

abdes avatar Jul 23 '23 01:07 abdes

Here is a minimal reproducible solution. https://github.com/MH-ZShearer/SourceGeneratorTest

The same exact code in a .NET 7.0 application works, but this .NET Framework 4.8 fails to compile with:

error CS0103: The name 'TestCommand' does not exist in the current context

I have tried v8.0, v8.1, and v8.2 and all of them provide the same issue. I am currently using VS v17.6.3.

It is worth noting that the generators are generating the expected code and the application works as expected, but only if there are no references in C# to the generated properties or commands. In this case, if we replace nameof(TestCommand) with the string literal "TestCommand", the application compiles as expected, but this is an unsustainable workaround.

SAME here!

HppZ avatar May 23 '24 08:05 HppZ

1, migrate packages.config file 2, migrate csproj file using CsprojToVs2017 3, done!

HppZ avatar May 23 '24 10:05 HppZ

@HppZ exactly, the problem seems to exist only in the legecy csproj style, using the upgrade-assistant tool to upgrade the project to the SDK style solved the problem for me too

akarboush avatar May 23 '24 14:05 akarboush