From 7d34044c2c9cf6b1fa45ff432455f65f5f001319 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 17 Mar 2026 14:06:13 +0000
Subject: [PATCH 1/2] Initial plan
From e11f8bc19cb7016d7574822735b48b4998ff3926 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 30 Mar 2026 07:58:16 +0000
Subject: [PATCH 2/2] Wire up IServiceProvider to ValidationContext in
DataAnnotations options validation
Pass the root IServiceProvider to ValidationContext when validating
DataAnnotations attributes on Options. This enables custom validation
attributes to resolve services via validationContext.GetService() or
validationContext.GetRequiredService().
Changes:
- Add new public constructor DataAnnotationValidateOptions(name, serviceProvider)
- Change ValidateDataAnnotations() to register using a factory that
captures and passes IServiceProvider to the new constructor
- Pass IServiceProvider through to all ValidationContext instances,
including nested ValidateObjectMembers and ValidateEnumeratedItems calls
- Update ref assembly with the new constructor
- Add tests verifying service resolution works and fails correctly
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/b340196e-dcb9-42de-ad3c-eb10b9d9199c
Co-authored-by: rosebyte <14963300+rosebyte@users.noreply.github.com>
---
...soft.Extensions.Options.DataAnnotations.cs | 2 +
.../src/DataAnnotationValidateOptions.cs | 25 ++++++++--
...OptionsBuilderDataAnnotationsExtensions.cs | 3 +-
.../OptionsBuilderTest.cs | 48 +++++++++++++++++++
4 files changed, 72 insertions(+), 6 deletions(-)
diff --git a/src/libraries/Microsoft.Extensions.Options.DataAnnotations/ref/Microsoft.Extensions.Options.DataAnnotations.cs b/src/libraries/Microsoft.Extensions.Options.DataAnnotations/ref/Microsoft.Extensions.Options.DataAnnotations.cs
index 874dd859fe83e8..90a7e45e3725c7 100644
--- a/src/libraries/Microsoft.Extensions.Options.DataAnnotations/ref/Microsoft.Extensions.Options.DataAnnotations.cs
+++ b/src/libraries/Microsoft.Extensions.Options.DataAnnotations/ref/Microsoft.Extensions.Options.DataAnnotations.cs
@@ -18,6 +18,8 @@ public partial class DataAnnotationValidateOptions<[System.Diagnostics.CodeAnaly
{
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The implementation of Validate method on this type will walk through all properties of the passed in options object, and its type cannot be statically analyzed so its members may be trimmed.")]
public DataAnnotationValidateOptions(string? name) { }
+ [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("The implementation of Validate method on this type will walk through all properties of the passed in options object, and its type cannot be statically analyzed so its members may be trimmed.")]
+ public DataAnnotationValidateOptions(string? name, System.IServiceProvider? serviceProvider) { }
public string? Name { get { throw null; } }
public Microsoft.Extensions.Options.ValidateOptionsResult Validate(string? name, TOptions options) { throw null; }
}
diff --git a/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/DataAnnotationValidateOptions.cs b/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/DataAnnotationValidateOptions.cs
index 2b85690478eff2..4b9fad94bbe662 100644
--- a/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/DataAnnotationValidateOptions.cs
+++ b/src/libraries/Microsoft.Extensions.Options.DataAnnotations/src/DataAnnotationValidateOptions.cs
@@ -26,8 +26,21 @@ public class DataAnnotationValidateOptions<[DynamicallyAccessedMembers(Dynamical
[RequiresUnreferencedCode("The implementation of Validate method on this type will walk through all properties of the passed in options object, and its type cannot be " +
"statically analyzed so its members may be trimmed.")]
public DataAnnotationValidateOptions(string? name)
+ : this(name, serviceProvider: null)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of .
+ ///
+ /// The name of the option.
+ /// An to be used for resolving services in .
+ [RequiresUnreferencedCode("The implementation of Validate method on this type will walk through all properties of the passed in options object, and its type cannot be " +
+ "statically analyzed so its members may be trimmed.")]
+ public DataAnnotationValidateOptions(string? name, IServiceProvider? serviceProvider)
{
Name = name;
+ _serviceProvider = serviceProvider;
}
///
@@ -35,6 +48,8 @@ public DataAnnotationValidateOptions(string? name)
///
public string? Name { get; }
+ private readonly IServiceProvider? _serviceProvider;
+
///
/// Validates a specific named options instance (or all when is null).
///
@@ -59,7 +74,7 @@ public ValidateOptionsResult Validate(string? name, TOptions options)
HashSet