microsoft / CsWinRT

C# language projection for the Windows Runtime
MIT License
554 stars 105 forks source link

[AOT | CsWinRT | BindableCustomProperty] Auto-generated code from CTK ObervableProperty do not get found during build time. #1689

Open RobsonPontin opened 3 months ago

RobsonPontin commented 3 months ago

Describe the bug

There are issues related to the CsWinRT/AOT auto-generated code to proper find the auto-generated code done by CommunityToolKit for [ObservableProperty], which leads to runtime errors since there are missing interfaces.

To Reproduce

Example:

Given a type called FolderMenuItem which has observable property:

[WinRT.BindableCustomProperty]
public partial class FolderMenuItem : ObservableObject
{
     [ObservableProperty]
     private string name = string.Empty;

     public string FolderFriendName { get; set; }
}

Actual result in the WinRTCustomBindableProperties.g.cs is missing the Name property:

partial class FolderMenuItem : global::Microsoft.UI.Xaml.Data.IBindableCustomPropertyImplementation
{
  global::Microsoft.UI.Xaml.Data.BindableCustomProperty global::Microsoft.UI.Xaml.Data.IBindableCustomPropertyImplementation.GetProperty(string name)
  {
    if (name == "FolderFriendlyName")
    {
      return new global::Microsoft.UI.Xaml.Data.BindableCustomProperty(
          true,
          false,
          "FolderFriendlyName",
          typeof(string),
          static (instance) => ((PhotosManager.Models.FolderMenuItem)instance).FolderFriendlyName,
          null,
          null,
          null);
    }
  }
}

Expected behavior

The CsWinRT auto-gen code should see any CTK auto-gen code and proper create the AOT mapping.

As a workaround for now I need to remove [WinRT.BindableCustomProperty] and create the interface myself:

partial class FolderMenuItem : global::Microsoft.UI.Xaml.Data.IBindableCustomPropertyImplementation
{
    global::Microsoft.UI.Xaml.Data.BindableCustomProperty global::Microsoft.UI.Xaml.Data.IBindableCustomPropertyImplementation.GetProperty(string name)
    {
        if (name == "Name")
        {
            return new global::Microsoft.UI.Xaml.Data.BindableCustomProperty(
                true,
                false,
                "Name",
                typeof(string),
                static (instance) => ((PhotosManager.Models.FolderMenuItem)instance).Name,
                null,
                null,
                null);
        }
        if (name == "FolderFriendlyName")
        {
          return new global::Microsoft.UI.Xaml.Data.BindableCustomProperty(
             true,
             false,
             "FolderFriendlyName",
             typeof(string),
             static (instance) => ((PhotosManager.Models.FolderMenuItem)instance).FolderFriendlyName,
             null,
             null,
             null);
        }

        return default;
    }

    global::Microsoft.UI.Xaml.Data.BindableCustomProperty global::Microsoft.UI.Xaml.Data.IBindableCustomPropertyImplementation.GetProperty(global::System.Type indexParameterType)
    {
        return default;
    }
}

Version Info

michael-hawker commented 3 months ago

FYI @Sergio0694 would this have to do with source generator ordering/dependency? i.e. the CsWinRT generator can't see the output of the MVVM Toolkit generator and therefore doesn't know there's a property?

Of course that'd be resolved by .NET 9 with partial properties and the next iteration of the MVVM Toolkit generator, right?

Sergio0694 commented 3 months ago

Yup (see my email reply as well), the right fix for this is just to switch to partial properties in the MVVM Toolkit 🙂 This is not a bug in CsWinRT, the current behavior is by design.

manodasanW commented 3 months ago

Leaving this open here just for awareness and for making sure we properly handle partial properties in our source generator.