From e3b4cbece58794e5ce4887ba4b5829406453a206 Mon Sep 17 00:00:00 2001 From: DevTekVE Date: Sun, 13 Jul 2025 11:42:36 +0200 Subject: [PATCH] Add AOT compatibility annotations and flags for FluentValidation - Mark relevant methods and properties with `[RequiresUnreferencedCode]` or `[DynamicDependency]` to support Ahead-Of-Time (AOT) compilation. - Add `` property to project files for compatibility metadata. - Suppress warnings where validators are expected to be preserved by user annotations. --- ...FluentValidation.AutoValidation.Endpoints.csproj | 1 + .../AutoValidationEndpointsConfiguration.cs | 4 +++- .../src/Extensions/EndpointRouteExtensions.cs | 13 ++++++++++++- .../FluentValidation.AutoValidation.Shared.csproj | 1 + .../src/Extensions/ServiceProviderExtensions.cs | 7 +++++++ 5 files changed, 24 insertions(+), 2 deletions(-) diff --git a/FluentValidation.AutoValidation.Endpoints/FluentValidation.AutoValidation.Endpoints.csproj b/FluentValidation.AutoValidation.Endpoints/FluentValidation.AutoValidation.Endpoints.csproj index 5019ec4..15b160f 100644 --- a/FluentValidation.AutoValidation.Endpoints/FluentValidation.AutoValidation.Endpoints.csproj +++ b/FluentValidation.AutoValidation.Endpoints/FluentValidation.AutoValidation.Endpoints.csproj @@ -11,6 +11,7 @@ SharpGrip FluentValidation AutoValidation Endpoints SharpGrip FluentValidation AutoValidation Endpoints is an extension of the FluentValidation library enabling automatic asynchronous validation in minimal APIs (endpoints). sharpgrip;validation;fluent-validation;endpoints;minimal-api + true diff --git a/FluentValidation.AutoValidation.Endpoints/src/Configuration/AutoValidationEndpointsConfiguration.cs b/FluentValidation.AutoValidation.Endpoints/src/Configuration/AutoValidationEndpointsConfiguration.cs index 4e82152..b3593c9 100644 --- a/FluentValidation.AutoValidation.Endpoints/src/Configuration/AutoValidationEndpointsConfiguration.cs +++ b/FluentValidation.AutoValidation.Endpoints/src/Configuration/AutoValidationEndpointsConfiguration.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Http.HttpResults; using SharpGrip.FluentValidation.AutoValidation.Endpoints.Results; @@ -9,6 +10,7 @@ public class AutoValidationEndpointsConfiguration /// /// Holds the overridden result factory. This property is meant for infrastructure and should not be used by application code. /// + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] public Type? OverriddenResultFactory { get; private set; } /// @@ -17,7 +19,7 @@ public class AutoValidationEndpointsConfiguration /// /// /// The custom result factory implementing . - public void OverrideDefaultResultFactoryWith() where TResultFactory : IFluentValidationAutoValidationResultFactory + public void OverrideDefaultResultFactoryWith<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TResultFactory>() where TResultFactory : IFluentValidationAutoValidationResultFactory { OverriddenResultFactory = typeof(TResultFactory); } diff --git a/FluentValidation.AutoValidation.Endpoints/src/Extensions/EndpointRouteExtensions.cs b/FluentValidation.AutoValidation.Endpoints/src/Extensions/EndpointRouteExtensions.cs index e6f6fbf..4b4de98 100644 --- a/FluentValidation.AutoValidation.Endpoints/src/Extensions/EndpointRouteExtensions.cs +++ b/FluentValidation.AutoValidation.Endpoints/src/Extensions/EndpointRouteExtensions.cs @@ -1,4 +1,5 @@ -using Microsoft.AspNetCore.Builder; +using System.Diagnostics.CodeAnalysis; +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; using SharpGrip.FluentValidation.AutoValidation.Endpoints.Filters; @@ -12,6 +13,11 @@ public static class EndpointRouteExtensions /// /// The route handler builder. /// The route handler builder. + /// + /// For AOT validation to work, the validator itself must be marked [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(YourValidator!)] to ensure it's preserved.
+ /// Otherwise, it will not be found at runtime and the validation will NOT happen.
+ ///
+ [RequiresUnreferencedCode("Requires unreferenced code to locate and access IValidator<> types at runtime, it only works for types that are known (and preserved) at compile time. See remarks for more details.")] public static RouteHandlerBuilder AddFluentValidationAutoValidation(this RouteHandlerBuilder routeHandlerBuilder) { routeHandlerBuilder.AddEndpointFilter(); @@ -24,6 +30,11 @@ public static RouteHandlerBuilder AddFluentValidationAutoValidation(this RouteHa /// /// The route group builder. /// The route group builder. + /// + /// For AOT validation to work, the validator itself must be marked as DynamicDependency to ensure it's preserved:[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(YourValidator!)]
+ /// Otherwise, it will not be found at runtime and the validation will NOT happen.
+ ///
+ [RequiresUnreferencedCode("Requires unreferenced code to locate and access IValidator<> types at runtime, it only works for types that are known (and preserved) at compile time. See remarks for more details.")] public static RouteGroupBuilder AddFluentValidationAutoValidation(this RouteGroupBuilder routeGroupBuilder) { routeGroupBuilder.AddEndpointFilter(); diff --git a/FluentValidation.AutoValidation.Shared/FluentValidation.AutoValidation.Shared.csproj b/FluentValidation.AutoValidation.Shared/FluentValidation.AutoValidation.Shared.csproj index eed5b58..0a3a3c0 100644 --- a/FluentValidation.AutoValidation.Shared/FluentValidation.AutoValidation.Shared.csproj +++ b/FluentValidation.AutoValidation.Shared/FluentValidation.AutoValidation.Shared.csproj @@ -11,6 +11,7 @@ SharpGrip FluentValidation AutoValidation Shared SharpGrip FluentValidation AutoValidation is an extension of the FluentValidation library enabling automatic asynchronous validation in MVC controllers and minimal APIs (endpoints). sharpgrip;validation;fluent-validation;mvc;endpoints;minimal-api + true diff --git a/FluentValidation.AutoValidation.Shared/src/Extensions/ServiceProviderExtensions.cs b/FluentValidation.AutoValidation.Shared/src/Extensions/ServiceProviderExtensions.cs index b15530f..f05d990 100644 --- a/FluentValidation.AutoValidation.Shared/src/Extensions/ServiceProviderExtensions.cs +++ b/FluentValidation.AutoValidation.Shared/src/Extensions/ServiceProviderExtensions.cs @@ -1,10 +1,17 @@ using System; using FluentValidation; +#if NET7_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif namespace SharpGrip.FluentValidation.AutoValidation.Shared.Extensions { public static class ServiceProviderExtensions { +#if NET7_0_OR_GREATER + [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(IValidator<>))] + [UnconditionalSuppressMessage("Aot", "IL3050", Justification = "Validators should be preserved by the compiler if the user has marked them with [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(YourValidator!)] or similar.")] +#endif public static object? GetValidator(this IServiceProvider serviceProvider, Type type) { return serviceProvider.GetService(typeof(IValidator<>).MakeGenericType(type));