IL2077/IL2080/IL2075 when trimming application using System.CommandLine.Hosting
Similar to #1465
/_/src/System.CommandLine.Hosting/HostingExtensions.cs(113,21): Trim analysis error IL2077: System.CommandLine.Hosting.HostingExtensions.<>c__DisplayClass6_0.<UseCommandHandler>b__1(IServiceCollection): 'serviceType' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors' in call to 'Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddTransient(IServiceCollection,Type)'. The field 'System.CommandLine.Hosting.HostingExtensions.<>c__DisplayClass6_0.handlerType' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
/_/src/System.CommandLine.Hosting/HostingExtensions.cs(116,17): Trim analysis error IL2080: System.CommandLine.Hosting.HostingExtensions.UseCommandHandler(IHostBuilder,Type,Type): 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicMethods' in call to 'System.Type.GetMethod(String)'. The field 'System.CommandLine.Hosting.HostingExtensions.<>c__DisplayClass6_0.handlerType' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
/_/src/System.CommandLine.NamingConventionBinder/ModelDescriptor.cs(38,9): Trim analysis error IL2075: System.CommandLine.NamingConventionBinder.ModelDescriptor.ConstructorDescriptors.get: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors', 'DynamicallyAccessedMemberTypes.NonPublicConstructors' in call to 'System.Type.GetConstructors(BindingFlags)'. The return value of method 'System.CommandLine.NamingConventionBinder.ModelDescriptor.ModelType.get' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
/_/src/System.CommandLine.NamingConventionBinder/ModelDescriptor.cs(47,9): Trim analysis error IL2075: System.CommandLine.NamingConventionBinder.ModelDescriptor.PropertyDescriptors.get: 'this' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicProperties', 'DynamicallyAccessedMemberTypes.NonPublicProperties' in call to 'System.Type.GetProperties(BindingFlags)'. The return value of method 'System.CommandLine.NamingConventionBinder.ModelDescriptor.ModelType.get' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
I worked around this by adding one entry like this:
[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(MyCommand.Handler))]
for each of my command handlers, and ignoring the 3 warnings, but this will blow in my face in the future, so proper support for ILTrimming is preferred.
I'm working on this. Not that complicated for System.CommandLine and System.CommandLine.Hosting.
For the reference, I am also seeing linking errors from System.CommandLine.NamingConventionBinder in my app:
.../system.commandline.namingconventionbinder/2.0.0-beta4.22272.1/lib/netstandard2.0/System.CommandLine.NamingConventionBinder.dll : error IL2104: Assembly 'System.CommandLine.NamingConventionBinder' produced trim warnings. For more information see https://aka.ms/dotnet-illink/libraries [/home/per/git/perlang/src/Perlang.ConsoleApp/Perlang.ConsoleApp.csproj]
System.CommandLine.NamingConventionBinder is heavily reliant on reflection and would need an almost complete rewrite in order to become trimmable.
Thanks for the feedback @jonsequitur. Are there any known workarounds to this apart from keeping <SuppressTrimAnalysisWarnings>true</SuppressTrimAnalysisWarnings> in my app? I'd rather be able to disable it, since there is a risk that it hides other real trimming-related problems in the app. (https://github.com/perlang-org/perlang/pull/347#issuecomment-1267420299)
I'm not aware of any.
We're planning to create a source generator that will replace System.CommandLine.NamingConventionBinder with something as concise but with all of the trimmability of the core System.CommandLine, but for that to be source code-compatible with the System.CommandLine.NamingConventionBinder API doesn't look feasible.