Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a DynamicallyAccessedMembers attribute to ViewBuilder.Create #288

Merged
merged 1 commit into from
Mar 31, 2023

Conversation

Numpsy
Copy link
Collaborator

@Numpsy Numpsy commented Mar 30, 2023

(sort of) refs #281.

So... I've been using FuncUI to build an app that i've been publishing as a self contained, trimmed, exe (it's built with .NET 7, but you can run it without having to have an appropriate .NET version installed, and has fewer files to care about).

For various reasons (many things being broken basically), I've had it on partial trim mode so that it only trims libs that are explicitly marked as trimmable, whilst waiting for thins to get fixed or improve elsewhere. (e.g. the completion of some work in Avalonia to help it work better with trimming).

In Avalonia 11 Preview 6, parts of Avalonia are marked as trimmable, so they will be trimmed now when they weren't before. This should be quite nice as it will remove controls you aren't using and such, but alas it also causes this to happen with FuncUI:

Exception Info: System.MissingMethodException: Cannot dynamically create an instance of type 'Avalonia.Controls.TreeView'. Reason: No parameterless constructor defined.
   at System.RuntimeType.ActivatorCache..ctor(RuntimeType)
   at System.RuntimeType.CreateInstanceDefaultCtor(Boolean, Boolean)
   at System.Activator.CreateInstance(Type, Boolean, Boolean)
   at System.Activator.CreateInstance(Type , Boolean)
   at System.Activator.CreateInstance(Type )
   at Avalonia.FuncUI.VirtualDom.Patcher.create(ViewDelta viewElement)
   at Avalonia.FuncUI.VirtualDom.VirtualDom.updateBorderRoot(Border host, FSharpOption`1 last, FSharpOption`1 next)
   at <StartupCode$Avalonia-FuncUI>.$Component.Update@24.Invoke()
   at Avalonia.Threading.JobRunner.Job.Avalonia.Threading.JobRunner.IJob.Run() in /_/src/Avalonia.Base/Threading/JobRunner.cs:line 193
   at Avalonia.Threading.JobRunner.RunJobs(Nullable`1) in /_/src/Avalonia.Base/Threading/JobRunner.cs:line 38
   at Avalonia.Win32.Win32Platform.WndProc(IntPtr, UInt32, IntPtr, IntPtr) in /_/src/Windows/Avalonia.Win32/Win32Platform.cs:line 267
   at Avalonia.Win32.Interop.UnmanagedMethods.DispatchMessage(MSG&)
   at Avalonia.Win32.Win32Platform.RunLoop(CancellationToken) in /_/src/Windows/Avalonia.Win32/Win32Platform.cs:line 215
   at Avalonia.Threading.Dispatcher.MainLoop(CancellationToken) in /_/src/Avalonia.Base/Threading/Dispatcher.cs:line 61
   at Avalonia.Controls.ApplicationLifetimes.ClassicDesktopStyleApplicationLifetime.Start(String[]) in /_/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs:line 122
   at Avalonia.ClassicDesktopStyleApplicationLifetimeExtensions.StartWithClassicDesktopLifetime(AppBuilder, String[], ShutdownMode ) in /_/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs:line 214

because the trimmer can't find any references to said constructor and therefore bins it.
Activator.CreateInstance is annotated to explain this and in C# there is a roslyn analyzer that will try to tell you about that so that you can annotate your own code to be compatible, but no such help in F#.

Anyway, I'm sure there are other code paths that have the same issue (e.g. the ones that create instances of things and use a constructor with parameters), but just doing this one fixes the issues i'm getting by making it retain all the default constructors for used controls, so I'm opening this to at least open the question on how this situation should be handled.

Copy link
Member

@JaggerJo JaggerJo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, excellent point. I can think of a few ways of fixing constructors with parameters. We can merge this already.

@JaggerJo JaggerJo merged commit 91b4b45 into fsprojects:master Mar 31, 2023
@Numpsy Numpsy deleted the rw/trim_2 branch March 31, 2023 09:50
@Numpsy
Copy link
Collaborator Author

Numpsy commented Mar 31, 2023

I hadn't tried it before, but fwiw this change also allows a self-contained/trimmed version of the control catalog to run, whereas without that it just crashed on startup because of missing constructors

Edit: With .Net 6 that is - with 7 full trimming still breaks itfor other reasons

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
2 participants