Add trim and AOT compatibility for release build scanner usage#273
Add trim and AOT compatibility for release build scanner usage#273Copilot wants to merge 13 commits into
Conversation
Co-authored-by: jfversluis <939291+jfversluis@users.noreply.github.com>
Co-authored-by: jfversluis <939291+jfversluis@users.noreply.github.com>
Co-authored-by: jfversluis <939291+jfversluis@users.noreply.github.com>
|
@copilot build errors |
Co-authored-by: jfversluis <939291+jfversluis@users.noreply.github.com>
... Fixed in c3e0a3e. Moved |
| <PackageReadmeFile>README.md</PackageReadmeFile> | ||
| <!-- Enable trimming support and indicate library is trim-safe --> | ||
| <IsTrimmable>true</IsTrimmable> | ||
| <EnableTrimAnalyzer>true</EnableTrimAnalyzer> |
There was a problem hiding this comment.
This should not be necessary, IsTrimmable=true or IsAotCompatible=true will enable the analyzer.
| [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(CameraView))] | ||
| [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(CameraViewHandler))] | ||
| [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(CameraBarcodeReaderView))] | ||
| [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(CameraBarcodeReaderViewHandler))] | ||
| [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(BarcodeGeneratorView))] | ||
| [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(BarcodeGeneratorViewHandler))] | ||
| [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(Readers.ZXingBarcodeReader))] |
There was a problem hiding this comment.
I don't think these are necessary and that they actually do anything 🤔 The AddHandler method already has the [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] on the handler type argument, so these seem redundant. There is no real need to add the DynamicDependency on the view type itself, at least not here.
| [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(BarcodeGeneratorViewHandler))] | ||
| [DynamicDependency(nameof(BarcodeGeneratorViewMapper))] | ||
| [DynamicDependency(nameof(MapUpdateBarcode))] |
There was a problem hiding this comment.
I don't understand these DynamicDependency attributes, why are they here? Also where are we accessing the BarcodeGeneratorViewMapper or MapUpdateBarcode methods by reflection? It seems those DD attributes should be used in that location and not here.
| [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(CameraView))] | ||
| [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(CameraViewHandler))] | ||
| [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(CameraBarcodeReaderView))] | ||
| [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(CameraBarcodeReaderViewHandler))] | ||
| [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(BarcodeGeneratorView))] | ||
| [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(BarcodeGeneratorViewHandler))] | ||
| public static MauiAppBuilder UseBarcodeReader<TBarcodeReader>(this MauiAppBuilder builder) where TBarcodeReader : class, Readers.IBarcodeReader |
There was a problem hiding this comment.
Even with these changes, the build produces the following warnings (from CI):
Build succeeded.
"D:\a\ZXing.Net.Maui\ZXing.Net.Maui\ZXing.Net.MAUI.sln" (default target) (1:2) ->
"D:\a\ZXing.Net.Maui\ZXing.Net.Maui\ZXing.Net.MAUI.Controls\ZXing.Net.MAUI.Controls.csproj" (default target) (3:27) ->
"D:\a\ZXing.Net.Maui\ZXing.Net.Maui\ZXing.Net.MAUI.Controls\ZXing.Net.MAUI.Controls.csproj" (Build target) (3:35) ->
(CoreCompile target) ->
D:\a\ZXing.Net.Maui\ZXing.Net.Maui\ZXing.Net.MAUI.Controls\HostBuilderExtensions.cs(86,4): warning IL2091: 'TImplementation' generic argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors' in 'Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddTransient<TService, TImplementation>(IServiceCollection)'. The generic parameter 'TBarcodeReader' of 'ZXing.Net.Maui.Controls.CameraViewExtensions.UseBarcodeReader<TBarcodeReader>(MauiAppBuilder)' 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. [D:\a\ZXing.Net.Maui\ZXing.Net.Maui\ZXing.Net.MAUI.Controls\ZXing.Net.MAUI.Controls.csproj::TargetFramework=net9.0-ios]
"D:\a\ZXing.Net.Maui\ZXing.Net.Maui\ZXing.Net.MAUI.sln" (default target) (1:2) ->
"D:\a\ZXing.Net.Maui\ZXing.Net.Maui\ZXing.Net.MAUI.Controls\ZXing.Net.MAUI.Controls.csproj" (default target) (3:27) ->
"D:\a\ZXing.Net.Maui\ZXing.Net.Maui\ZXing.Net.MAUI.Controls\ZXing.Net.MAUI.Controls.csproj" (Build target) (3:41) ->
D:\a\ZXing.Net.Maui\ZXing.Net.Maui\ZXing.Net.MAUI.Controls\HostBuilderExtensions.cs(86,4): warning IL2091: 'TImplementation' generic argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors' in 'Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddTransient<TService, TImplementation>(IServiceCollection)'. The generic parameter 'TBarcodeReader' of 'ZXing.Net.Maui.Controls.CameraViewExtensions.UseBarcodeReader<TBarcodeReader>(MauiAppBuilder)' 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. [D:\a\ZXing.Net.Maui\ZXing.Net.Maui\ZXing.Net.MAUI.Controls\ZXing.Net.MAUI.Controls.csproj::TargetFramework=net9.0-windows10.0.19041]
"D:\a\ZXing.Net.Maui\ZXing.Net.Maui\ZXing.Net.MAUI.sln" (default target) (1:2) ->
"D:\a\ZXing.Net.Maui\ZXing.Net.Maui\ZXing.Net.MAUI.Controls\ZXing.Net.MAUI.Controls.csproj" (default target) (3:27) ->
"D:\a\ZXing.Net.Maui\ZXing.Net.Maui\ZXing.Net.MAUI.Controls\ZXing.Net.MAUI.Controls.csproj" (Build target) (3:28) ->
D:\a\ZXing.Net.Maui\ZXing.Net.Maui\ZXing.Net.MAUI.Controls\HostBuilderExtensions.cs(86,4): warning IL2091: 'TImplementation' generic argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors' in 'Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddTransient<TService, TImplementation>(IServiceCollection)'. The generic parameter 'TBarcodeReader' of 'ZXing.Net.Maui.Controls.CameraViewExtensions.UseBarcodeReader<TBarcodeReader>(MauiAppBuilder)' 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. [D:\a\ZXing.Net.Maui\ZXing.Net.Maui\ZXing.Net.MAUI.Controls\ZXing.Net.MAUI.Controls.csproj::TargetFramework=net9.0]
"D:\a\ZXing.Net.Maui\ZXing.Net.Maui\ZXing.Net.MAUI.sln" (default target) (1:2) ->
"D:\a\ZXing.Net.Maui\ZXing.Net.Maui\ZXing.Net.MAUI.Controls\ZXing.Net.MAUI.Controls.csproj" (default target) (3:27) ->
"D:\a\ZXing.Net.Maui\ZXing.Net.Maui\ZXing.Net.MAUI.Controls\ZXing.Net.MAUI.Controls.csproj" (Build target) (3:29) ->
D:\a\ZXing.Net.Maui\ZXing.Net.Maui\ZXing.Net.MAUI.Controls\HostBuilderExtensions.cs(86,4): warning IL2091: 'TImplementation' generic argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors' in 'Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddTransient<TService, TImplementation>(IServiceCollection)'. The generic parameter 'TBarcodeReader' of 'ZXing.Net.Maui.Controls.CameraViewExtensions.UseBarcodeReader<TBarcodeReader>(MauiAppBuilder)' 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. [D:\a\ZXing.Net.Maui\ZXing.Net.Maui\ZXing.Net.MAUI.Controls\ZXing.Net.MAUI.Controls.csproj::TargetFramework=net9.0-android]
"D:\a\ZXing.Net.Maui\ZXing.Net.Maui\ZXing.Net.MAUI.sln" (default target) (1:2) ->
"D:\a\ZXing.Net.Maui\ZXing.Net.Maui\ZXing.Net.MAUI.Controls\ZXing.Net.MAUI.Controls.csproj" (default target) (3:27) ->
"D:\a\ZXing.Net.Maui\ZXing.Net.Maui\ZXing.Net.MAUI.Controls\ZXing.Net.MAUI.Controls.csproj" (Build target) (3:40) ->
D:\a\ZXing.Net.Maui\ZXing.Net.Maui\ZXing.Net.MAUI.Controls\HostBuilderExtensions.cs(86,4): warning IL2091: 'TImplementation' generic argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors' in 'Microsoft.Extensions.DependencyInjection.ServiceCollectionServiceExtensions.AddTransient<TService, TImplementation>(IServiceCollection)'. The generic parameter 'TBarcodeReader' of 'ZXing.Net.Maui.Controls.CameraViewExtensions.UseBarcodeReader<TBarcodeReader>(MauiAppBuilder)' 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. [D:\a\ZXing.Net.Maui\ZXing.Net.Maui\ZXing.Net.MAUI.Controls\ZXing.Net.MAUI.Controls.csproj::TargetFramework=net9.0-maccatalyst]
5 Warning(s)
0 Error(s)
The actual fix should be the following:
| [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(CameraView))] | |
| [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(CameraViewHandler))] | |
| [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(CameraBarcodeReaderView))] | |
| [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(CameraBarcodeReaderViewHandler))] | |
| [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(BarcodeGeneratorView))] | |
| [DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(BarcodeGeneratorViewHandler))] | |
| public static MauiAppBuilder UseBarcodeReader<TBarcodeReader>(this MauiAppBuilder builder) where TBarcodeReader : class, Readers.IBarcodeReader | |
| public static MauiAppBuilder UseBarcodeReader<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TBarcodeReader>(this MauiAppBuilder builder) | |
| where TBarcodeReader : class, Readers.IBarcodeReader |
Also I suggest turning on TreatWarningsAsErrors to enforce the warnings produced by the trimming (and maybe later AOT) analyzers.
simonrozsival
left a comment
There was a problem hiding this comment.
- Remove
[DynamicDependency]attributes, they are not necessary - Add the DAM attribute to
TBarcodeReaderas suggested in a previous comment - Turn on
TreatWarningsAsErrorsfor projects withIsTrimmableturned on
|
@copilot address issues and seems like we need to rebase to resolve conflicts |
Rebase completed successfully onto main branch (4be5b83). The branch now includes: ✅ Updated to .NET 10 target frameworks The project file conflicts were resolved by keeping both the trimming safety properties AND the updated dependencies from main. A force push to |
|
@copilot rebase and resolve conflicts |
Rebase completed successfully in commit a3fa365. The branch has been rebased onto main (4be5b83) with all conflicts resolved. Updated: The project files now contain both the updated dependencies from main AND the trimming safety properties. A force push is required to update the remote branch since the history was rewritten. |
|
@copilot first comment ZXing.Net.MAUI.Controls/ZXing.Net.MAUI.Controls.csproj |
Co-authored-by: jfversluis <939291+jfversluis@users.noreply.github.com>
Done in a9dae97. Added |
|
@copilot next comment ZXing.Net.MAUI.Controls/ZXing.Net.MAUI.Controls.csproj |
Co-authored-by: jfversluis <939291+jfversluis@users.noreply.github.com>
Done in fd84fa2. Removed |
|
@copilot next comment ZXing.Net.MAUI.Controls/HostBuilderExtensions.cs |
Co-authored-by: jfversluis <939291+jfversluis@users.noreply.github.com>
Done in 8dac80a. Removed redundant |
|
@copilot next comment ZXing.Net.MAUI/BarcodeGeneratorViewHandler.cs |
The attributes preserve members accessed by the MAUI handler system. When
The However, if there's a better location for these attributes or an alternative approach you'd recommend, I'm happy to adjust. The key requirement is preserving the mapper fields and the methods they reference. |
|
@copilot last comment ZXing.Net.MAUI.Controls/HostBuilderExtensions.cs Build succeeded. 5 Warning(s) Suggested change |
…rameter Co-authored-by: jfversluis <939291+jfversluis@users.noreply.github.com>
Fixed in 565c7ea. Added |
Merge current main and replace broad DynamicDependency preservation with precise trim/AOT annotations. Mark the library projects as AOT-compatible, enforce warnings as errors, and document that normal UseBarcodeReader usage should not require trimmer exceptions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove leftover documentation noise and restore the no-op line ending change so the PR only contains the trim/AOT compatibility work. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
This updates PR #273 against current
mainand narrows the trim/AOT fix to the code paths that still need it:ZXing.Net.MAUIandZXing.Net.MAUI.Controlsas AOT-compatible with<IsAotCompatible>true</IsAotCompatible>.<TreatWarningsAsErrors>true</TreatWarningsAsErrors>for both library projects so trim/AOT analyzer warnings fail builds instead of becoming easy to miss.[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]to the customUseBarcodeReader<TBarcodeReader>()type parameter becauseAddTransient<TService,TImplementation>()requires public constructors on the implementation type.DynamicDependencypreservation approach. The MAUI handler registration APIs already annotate handler constructor requirements, and the handler mappers/map methods are statically referenced by the constructors.UseBarcodeReader()usage should not require linker/trimmer exceptions, while custom barcode reader implementations need DI-activatable public constructors.Decisions
TBarcodeReaderbecause it fixes the DI analyzer path called out in review (IL2091).DynamicDependency; there is no concrete reflection path in this library that needs those attributes.IsAotCompatiblerather than separately addingIsTrimmable/EnableTrimAnalyzer; the AOT-compatible library setting is the stronger declaration and enables the relevant analyzer set.Validation
dotnet build ZXing.Net.MAUI/ZXing.Net.MAUI.csproj --configuration Release --framework net10.0 --no-restore --verbosity minimaldotnet build ZXing.Net.MAUI.Controls/ZXing.Net.MAUI.Controls.csproj --configuration Release --framework net10.0 --no-restore --verbosity minimaldotnet build ZXing.Net.MAUI/ZXing.Net.MAUI.csproj --configuration Release --framework net10.0-android --no-restore --verbosity minimaldotnet build ZXing.Net.MAUI.Controls/ZXing.Net.MAUI.Controls.csproj --configuration Release --framework net10.0-android --no-restore --verbosity minimaldotnet test ZXing.Net.MAUI.Tests/ZXing.Net.MAUI.Tests.csproj --configuration Release --no-restore --verbosity minimal(21 passed)I also attempted a full solution Release build. The library and Android targets built, but the local Apple sample-app targets could not complete because the installed Xcode is 26.2 while the local .NET iOS/MacCatalyst packs require Xcode 26.4.
Fixes #207