Skip to content

feat: create clients through the AWS SDK static factories on .NET 10+ - #68

Merged
Blind-Striker merged 2 commits into
aot/native-aot-test-lanefrom
aot/generic-path-static-factories
Oct 23, 2026
Merged

Blind-Striker merged 2 commits into
aot/native-aot-test-lanefrom
aot/generic-path-static-factories

Conversation

@Blind-Striker

@Blind-Striker Blind-Striker commented Oct 23, 2026 •

Copy link
Copy Markdown
Member

Stack (review bottom-up, merge as one stack): #62 base, #66 the #63 fix, #67 Native AOT test lane, #68 static-factory generic path, #70 slim generator, #71 public docs, #72 internal docs and 3.0.0, #73 reflection-free test, #74 package consumer in CI, #75 convention clean-up, #76 service catalog refresh.

Goal of the stack: 3.0.0, where existing consumers upgrade without code changes, both packages support Native AOT on net10.0/net11.0, and the libraries use no runtime reflection for types the compiler can see (a JIT-only fallback covers the rest).

This PR

Session.CreateClientByInterface<TClient>(), which every AddAwsService*/TryAdd* overload calls, now uses the AWS SDK v4 static factories (TClient.CreateDefaultClientConfig(), TClient.CreateDefaultServiceClient(...)) when the injected helper is exactly the default SessionReflection. The endpoint is looked up by ClientConfig.ServiceId, which equals the private serviceMetadata.ServiceId for all 118 pinned AWS services. S3 ForcePathStyle is set through a string-named UnsafeAccessor, so Core needs no AWSSDK.S3 reference. No reflection and no generator on this path, so it also works in F#/VB.

Behaviour is unchanged: the same validation order and messages, the same config values, and client construction failures still wrapped in TargetInvocationException with the original inner exception. A custom or mocked ISessionReflection keeps the previous path call for call. Test fixtures: the mock static factories now pass on the config they receive, and MockClientConfig sets the mock service id.

Test names follow the Should convention.

Verification

New tests fail on the base and pass after (non-conventional client name, factory exception identity, config identity). Core 103 (net10/11), Integration 240 x3, Extensions 62, Functional 50 x2; Native AOT lane 35/35 on net10/net11.

@Blind-Striker
Blind-Striker added this pull request to stack #69 October 23, 2026 11:12
@github-actions

Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

CreateClientByInterface<TClient>() is what every AddAwsService/TryAdd*
overload calls. When the session uses the default SessionReflection, it now
creates the config and the client with TClient.CreateDefaultClientConfig()
and TClient.CreateDefaultServiceClient(), looks the endpoint up by
ClientConfig.ServiceId (equal to the private serviceMetadata.ServiceId for
every pinned AWS service), and sets S3's ForcePathStyle through a
string-named UnsafeAccessor, so Core needs no AWSSDK.S3 reference. No
reflection and no source generator on this path.

Behaviour is unchanged: the same validation order and messages, the same
config values, and client construction failures still surface as
TargetInvocationException with the original inner exception. A custom or
mocked ISessionReflection keeps today's path call for call.

The mock static factories now pass on the configuration they receive, and
MockClientConfig carries the mock service id.
@Blind-Striker
Blind-Striker force-pushed the aot/generic-path-static-factories branch from fcdcd06 to d181a96 Compare October 23, 2026 20:24
@Blind-Striker
Blind-Striker marked this pull request as ready for review October 23, 2026 21:54
@Blind-Striker
Blind-Striker merged commit 49573c2 into master Oct 23, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant