Skip to content

DI and Hosting tests failing on iOS with DefaultConstructorConstraint validation errors #127448

@github-actions

Description

@github-actions

Description

Multiple Microsoft.Extensions tests started failing on iOS and likely all mobile platforms with generic constraint validation errors in CallSiteFactory.ValidateTrimmingAnnotations.

Affected Test Assemblies

  1. Microsoft.Extensions.DependencyInjection.Tests - 7 failures
  2. Microsoft.Extensions.Hosting.Unit.Tests - 7 failures
  3. Microsoft.Extensions.Logging.EventSource.Tests - 8 failures
  4. System.Runtime.Loader.DefaultContext.Tests - 1 failure

Failure Pattern

All failing DI tests show the same error:

System.ArgumentException : Generic implementation type 'Microsoft.Extensions.DependencyInjection.Specification.Fakes.ClassWithStructConstraint`1' has a DefaultConstructorConstraint ('new()' constraint), but the generic service type 'Microsoft.Extensions.DependencyInjection.Specification.Fakes.IFakeOpenGenericService`1' doesn't.
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.ValidateTrimmingAnnotations(Type serviceType, Type[] serviceTypeGenericArguments, Type implementationType, Type[] implementationTypeGenericArguments)

Root Cause Analysis

The validation logic in CallSiteFactory.ValidateTrimmingAnnotations (lines 120-125) rejects cases where the implementation type has a new() constraint but the service type doesn't. This validation appears to be overly strict:

  • ClassWithStructConstraint<T> has a where T : struct constraint
  • In C#, struct constraints implicitly include new() (represented in IL as NotNullableValueTypeConstraint | DefaultConstructorConstraint)
  • The interface IFakeOpenGenericService<T> has no constraints
  • The validation throws even though this is a valid and safe registration

The tests (CallSiteFactoryTest.CreateCallSite_ReturnsService_IfClosedTypeSatisfiesStructGenericConstraint, etc.) were specifically written to verify that generic constraint matching works correctly, but the new validation logic rejects them outright.

Suspected Recent Change

The ValidateTrimmingAnnotations method and the TrimmingAnnotationsDoNotMatch_NewConstraint error message appear to have been added recently, though the exact introducing commit is unclear from shallow clone history.

This validation may be necessary for trimming correctness on NativeAOT/mobile, but the current implementation breaks legitimate scenarios where:

  • The implementation has a more restrictive constraint (e.g., struct)
  • The service has a less restrictive constraint (e.g., none)
  • The concrete type being resolved satisfies both

Failure Details

Build: https://dev.azure.com/dnceng-public/public/_build/results?buildId=1397424
Date: 2026-04-27

Sample Helix Job (iossimulator-arm64 CoreCLR):
Job ID: 7da59944-242f-4296-8a21-1a36fe1d0562

DI.Tests failures:

  • CreateCallSite_ReturnsService_IfClosedTypeSatisfiesStructGenericConstraint
  • CreateCallSite_Throws_IfClosedTypeDoesNotSatisfyStructGenericConstraint
  • CreateCallSite_Throws_IfClosedTypeDoesNotSatisfyNewGenericConstraint
  • CreateCallSite_ReturnsService_IfClosedTypeSatisfiesNewGenericConstraint
  • CreateCallSite_ReturnsMatchingTypesThatMatchCorrectConstraints (3 variants)

Console log excerpt (sanitized):

Tests run: 696 Passed: 675 Failed: 7 Ignored: 14
System.ArgumentException : Generic implementation type has a DefaultConstructorConstraint ('new()' constraint), but the generic service type doesn't.

Platform Coverage

Confirmed failures on:

  • iossimulator-arm64 (CoreCLR & Mono)
  • tvos-arm64 (CoreCLR & Mono)
  • maccatalyst-arm64/x64 (CoreCLR & Mono)
  • android-arm/arm64/x64/x86 (CoreCLR & Mono)

Recommended Fix

The validation logic should be relaxed to allow implementation types with stricter constraints than the service type, since this is safe and commonly used. The check should only reject cases where the implementation's constraints are incompatible with the service's constraints (e.g., implementation requires class but service requires struct).

Alternatively, if the strict validation is required for mobile NativeAOT correctness, the affected tests should be conditioned with [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMobileAot))] or similar.

Note

🔒 Integrity filter blocked 3 items

The following items were blocked because they don't meet the GitHub integrity level.

  • #126023 search_pull_requests: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".
  • #124461 search_pull_requests: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".
  • #108513 search_pull_requests: has lower integrity than agent requires. The agent cannot read data with integrity below "approved".

To allow these resources, lower min-integrity in your GitHub frontmatter:

tools:
  github:
    min-integrity: approved  # merged | approved | unapproved | none

Generated by Mobile Platform Failure Scanner · ● 4.2M ·

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions