dotnet / maui

.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.
https://dot.net/maui
MIT License
22.24k stars 1.76k forks source link

EntryPointNotFoundException in Release mode with nested resources #23804

Open StephaneDelcroix opened 3 months ago

StephaneDelcroix commented 3 months ago

Description

Using XamlC, I get an EntryPointNotFoundException with nested resources

Steps to Reproduce

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        x:Class="Microsoft.Maui.Controls.Xaml.UnitTests.EntryPointNotFound">
    <StackLayout x:Name="sl">
        <StackLayout.Resources>
            <x:Object x:Key="resource"  />
        </StackLayout.Resources>
        <Label x:Name="l0"/>
        <Label x:Name="l1" />
    </StackLayout>
</ContentPage>

(and the associated code behind for test:)

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Maui.ApplicationModel;
using Microsoft.Maui.Controls.Core.UnitTests;
using Microsoft.Maui.Controls.Shapes;
using Microsoft.Maui.Dispatching;
using Microsoft.Maui.UnitTests;
using NUnit.Framework;

namespace Microsoft.Maui.Controls.Xaml.UnitTests;

public partial class EntryPointNotFound : ContentPage
{
    public EntryPointNotFound() => InitializeComponent();
    public EntryPointNotFound(bool useCompiledXaml)
    {
        //this stub will be replaced at compile time
    }

    [TestFixture]
    class Tests
    {
        [SetUp]
        public void Setup()
        {
            Application.SetCurrentApplication(new MockApplication());
            DispatcherProvider.SetCurrent(new DispatcherProviderStub());
        }

        [TearDown] public void TearDown() => AppInfo.SetCurrent(null);

        [Test]
        public void XSharedIsSupportedOnResources([Values(false, true)]bool useCompiledXaml)
        {
            var layout = new EntryPointNotFound(useCompiledXaml);
        }
    }
}

Link to public reproduction project repository

No response

Version with bug

9.0.0-preview.6.24327.7

Is this a regression from previous behavior?

Not sure, did not test other versions

Last version that worked well

Unknown/Other

Affected platforms

iOS, Android, Windows, macOS, Other (Tizen, Linux, etc. not supported by Microsoft directly)

Affected platform versions

No response

Did you find any workaround?

No response

Relevant log output

No response

github-actions[bot] commented 3 months ago

Hi I'm an AI powered bot that finds similar issues based off the issue title.

Please view the issues below to see if they solve your problem, and if the issue describes your problem please consider closing this one and thumbs upping the other issue to help us prioritize it. Thank you!

Open similar issues:

Closed similar issues:

Note: You can give me feedback by thumbs upping or thumbs downing this comment.

omghb commented 1 month ago

We get the same exception by the compiled binding:

image

Workaround: We had to replace a few Bindings with DataTriggers with the same Binding applied. I assume that DataTrigger Bindings are not using compiled bindings. However, we have a lot other similar Bindings on the same Pages which work correctly.

omghb commented 1 month ago

Update: The generated code for the compiled binding uses the wrong type to cast.

// Property of the DataModel
public IReadOnlyList<AnalogOutputNeutralConfigModel> AvailableNeutralConfigs { get; }

The casting to IReadOnlyCollection<FaultType> is wrong here:

// Generated code in the Page
bindingExtension22.Converter = greater;
bindingExtension22.Path = "AvailableNeutralConfigs.Count";
bindingExtension22.TypedBinding = new TypedBinding<AnalogOutputSignalModel, int>(delegate(AnalogOutputSignalModel P_0)
{
    object obj6 = P_0;
    if (obj6 != null)
    {
        obj6 = ((AnalogOutputSignalModel)obj6).AvailableNeutralConfigs;
        if (obj6 != null)
        {
            return (((IReadOnlyCollection<FaultType>)obj6).Count, true);
        }
    }
    return default((int, bool));
}, null, new Tuple<Func<AnalogOutputSignalModel, object>, string>[2]
{
    new Tuple<Func<AnalogOutputSignalModel, object>, string>((AnalogOutputSignalModel P_0) => P_0, "AvailableNeutralConfigs"),
    new Tuple<Func<AnalogOutputSignalModel, object>, string>((AnalogOutputSignalModel P_0) => P_0.AvailableNeutralConfigs, "Count")
});
BindingBase binding21 = ((IMarkupExtension<BindingBase>)bindingExtension22).ProvideValue((IServiceProvider)null);
grid6.SetBinding(VisualElement.IsVisibleProperty, binding21);

Note: AnalogOutputNeutralConfigModel is a reference type (record), FaultType is a value type (enum).