Improve linking of Microsoft.Maui.Controls.* assemblies
- Dominant language
- C#
- Stars
- 23.3k
- Forks
- 2k
- Avg merge
- 1d 10h
- Merged PRs (30d)
- 297
Description
### Description
#### Control -> Handler Mapping
https://github.com/dotnet/maui/blob/1ba45f950315e7eb3a805948ec4bb980278b6b06/src/Controls/src/Xaml/Hosting/AppHostBuilderExtensions.cs#L49-L59
We have this massive list of direct references to XAML controls to handlers.
We could use something like this: https://github.com/dotnet/maui/issues/7258
#### Linking
Initially from https://github.com/dotnet/maui/pull/5028#issuecomment-1059565674
The issue is that Xaml is a form of code that the trimmer can't see. It can reference Types, and since the trimmer can't see which Types it uses, the trimmer doesn't know it needs to keep those Types.
I can think of the following options to resolve this:
1. Don't mark Microsoft.Maui.Controls as "Trimmable".
- We can still take some of the other changes here to resolve trimmer warnings, and possibly trim `Microsoft.Maui.dll`. This would be at least a step in the right direction.
2. Take this change as is. And if someone is using LoadFromXaml in their app, instruct them to add `` to their .csproj. This will instruct the trimmer to preserve the entire assembly. That way people who don't use LoadFromXaml can save the size off their apps. And people who do use it can make it work.
3. We could add a `[DynamicDependency]` on the LoadFromXaml API. This way, if this method is used in the app, the Types can be preserved. However, there are the following drawbacks with this approach:
1. We would really want to say that _all_ types in the Microsoft.Maui.Controls assembly be preserved. That way we wouldn't have to list each Type that could be used in Xaml. However, the trimmer doesn't have this feature (yet). We would have to ask for it to be implemented to say `[DynamicDependency(DynammicallyAccessedMemberTypes.All, "*", "Microsoft.Maui.Controls")]`.
2. This would only address the issue for our built-in controls. It wouldn't solve the problem for 3rd party extenders who wanted to allow their control assemblies to be trimmed.
4. We could add a [Feature Switch](https://github.com/dotnet/designs/blob/main/accepted/2020/feature-switch.md) to the `LoadFromXaml` behavior. Let's call it `Microsoft.Maui.LoadFromXaml.IsSupported`. When `LoadFromXaml.IsSupported=false`, calling LoadFromXaml will throw an exception instructing the developer to set `LoadFromXaml.IsSupported=true`. By default in a trimmed, Release built version of an app, `LoadFromXaml.IsSupported` will be `false`. For all other times, it will be `true`. The benefit that this approach has is when `LoadFromXaml.IsSupported=true` we can use an [ILLink.Descriptor.xml](https://github.com/dotnet/linker/blob/main/docs/data-formats.md#descriptor-format) file that will tell the trimmer "when LoadFromXaml.IsSupported=true, then preserve this whole assembly".
1. 3rd party extenders could also follow this approach. That way their control assemblies can be marked as "Trimmable", but when LoadFromXaml is enabled, their whole assembly can be preserved as well.
Contributor guide
Assessment
This issue has not been assessed yet.