Skip to content

Commit aa8b029

Browse files
committed
feat: update AWS SDK references and enhance Native AOT support with trimming descriptors
1 parent 98bde31 commit aa8b029

File tree

11 files changed

+101
-14
lines changed

11 files changed

+101
-14
lines changed
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<linker>
2-
<assembly fullname="Amazon.Extensions.NETCore.Setup">
3-
<!-- Preserve the whole generic type (safer and still small) -->
2+
<assembly fullname="AWSSDK.Extensions.NETCore.Setup">
43
<type fullname="Amazon.Extensions.NETCore.Setup.ClientFactory`1" preserve="all" />
54
</assembly>
65
</linker>

src/LocalStack.Client.Extensions/LocalStack.Client.Extensions.csproj

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,13 @@
2525
</PropertyGroup>
2626

2727
<ItemGroup>
28-
<TrimmerRootDescriptor Include="ILLink.Descriptors.xml" />
28+
<!-- Root descriptor lives at package root for easy path reference -->
29+
<None Include="ILLink.Descriptors.xml" Pack="true" PackagePath="" />
30+
31+
<!-- The transitive props goes under buildTransitive -->
32+
<None Include="buildTransitive\\localstack.extensions.trimming.props"
33+
Pack="true"
34+
PackagePath="buildTransitive\\" />
2935
</ItemGroup>
3036

3137
<ItemGroup>

src/LocalStack.Client.Extensions/README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,27 @@ Localstack.NET is an easy-to-use .NET client for [LocalStack](https://github.com
3232
- [.NET Standard 2.0](https://docs.microsoft.com/en-us/dotnet/standard/net-standard)
3333
- [.NET Framework 4.7.2 and Above](https://dotnet.microsoft.com/download/dotnet-framework)
3434

35+
## ⚡ Native AOT & Trimming Status
36+
37+
> **Heads‑up for `dotnet publish -p:PublishAot=true` / `PublishTrimmed=true` users**
38+
39+
- **v2.0.0 GA ships without Native AOT support.**
40+
The current build still relies on reflection for some AWS SDK internals.
41+
- Public entry points that touch reflection are tagged with
42+
`[RequiresDynamicCode]` / `[RequiresUnreferencedCode]`.
43+
- You’ll see IL3050 / IL2026 warnings at compile time (promoted to errors in a strict AOT publish).
44+
- We ship the necessary linker descriptor with **`LocalStack.Client.Extensions`** to keep the private
45+
`ClientFactory<T>` members alive. No extra steps on your side.
46+
- Until the reflection‑free, source‑generated path lands (work in progress in
47+
[draft PR #49](https://github.com/localstack-dotnet/localstack-dotnet-client/pull/49) and tracked on
48+
[roadmap #48](https://github.com/localstack-dotnet/localstack-dotnet-client/discussions/48)):
49+
1. **Suppress** the warnings in your app *or* call the APIs that don’t rely on reflection.
50+
2. If you hit a runtime “missing member” error, ensure you’re on AWS SDK v4 **≥ 4.1.\*** and include the
51+
concrete `AWSSDK.*` package you’re instantiating.
52+
53+
> **Planned** – v2.1 will introduce an AOT‑friendly factory that avoids reflection entirely; once you
54+
> migrate to that API the warnings disappear.
55+
3556
### Build & Test Matrix
3657

3758
| Category | Platform/Type | Status | Description |
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Project>
2+
<!--
3+
Make the descriptor available to *any* project that references
4+
LocalStack.Client.Extensions (directly or transitively).
5+
-->
6+
<ItemGroup>
7+
<TrimmerRootDescriptor Include="ILLink.Descriptors.xml"
8+
Condition=" '$(EnableAotAnalyzer)' == 'true' Or
9+
'$(PublishTrimmed)' == 'true' Or
10+
'$(PublishAot)' == 'true' " />
11+
</ItemGroup>
12+
</Project>

src/LocalStack.Client/Options/ConfigOptions.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
namespace LocalStack.Client.Options;
22

3+
#if NET8_0_OR_GREATER
4+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)]
5+
#endif
36
public class ConfigOptions : IConfigOptions
47
{
58
public ConfigOptions()

src/LocalStack.Client/Options/LocalStackOptions.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
namespace LocalStack.Client.Options;
22

3+
#if NET8_0_OR_GREATER
4+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)]
5+
#endif
36
public class LocalStackOptions : ILocalStackOptions
47
{
58
public LocalStackOptions()

src/LocalStack.Client/Options/SessionOptions.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
namespace LocalStack.Client.Options;
22

3+
#if NET8_0_OR_GREATER
4+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties)]
5+
#endif
36
public class SessionOptions : ISessionOptions
47
{
58
public SessionOptions()

src/LocalStack.Client/README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,27 @@ Localstack.NET is an easy-to-use .NET client for [LocalStack](https://github.com
3232
- [.NET Standard 2.0](https://docs.microsoft.com/en-us/dotnet/standard/net-standard)
3333
- [.NET Framework 4.7.2 and Above](https://dotnet.microsoft.com/download/dotnet-framework)
3434

35+
## ⚡ Native AOT & Trimming Status
36+
37+
> **Heads‑up for `dotnet publish -p:PublishAot=true` / `PublishTrimmed=true` users**
38+
39+
- **v2.0.0 GA ships without Native AOT support.**
40+
The current build still relies on reflection for some AWS SDK internals.
41+
- Public entry points that touch reflection are tagged with
42+
`[RequiresDynamicCode]` / `[RequiresUnreferencedCode]`.
43+
- You’ll see IL3050 / IL2026 warnings at compile time (promoted to errors in a strict AOT publish).
44+
- We ship the necessary linker descriptor with **`LocalStack.Client.Extensions`** to keep the private
45+
`ClientFactory<T>` members alive. No extra steps on your side.
46+
- Until the reflection‑free, source‑generated path lands (work in progress in
47+
[draft PR #49](https://github.com/localstack-dotnet/localstack-dotnet-client/pull/49) and tracked on
48+
[roadmap #48](https://github.com/localstack-dotnet/localstack-dotnet-client/discussions/48)):
49+
1. **Suppress** the warnings in your app *or* call the APIs that don’t rely on reflection.
50+
2. If you hit a runtime “missing member” error, ensure you’re on AWS SDK v4 **≥ 4.1.\*** and include the
51+
concrete `AWSSDK.*` package you’re instantiating.
52+
53+
> **Planned** – v2.1 will introduce an AOT‑friendly factory that avoids reflection entirely; once you
54+
> migrate to that API the warnings disappear.
55+
3556
### Build & Test Matrix
3657

3758
| Category | Platform/Type | Status | Description |

src/LocalStack.Client/Session.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,9 @@ public TClient CreateClientByImplementation<TClient>(bool useServiceUrl = false)
3232
#endif
3333
public AmazonServiceClient CreateClientByImplementation(
3434
#if NET8_0_OR_GREATER
35-
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicFields)]Type implType,
36-
#else
37-
Type implType,
35+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicFields)]
3836
#endif
37+
Type implType,
3938
bool useServiceUrl = false)
4039
{
4140
if (!useServiceUrl && string.IsNullOrWhiteSpace(_sessionOptions.RegionName))
@@ -82,10 +81,9 @@ public AmazonServiceClient CreateClientByInterface<TClient>(bool useServiceUrl =
8281

8382
public AmazonServiceClient CreateClientByInterface(
8483
#if NET8_0_OR_GREATER
85-
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicFields)]Type serviceInterfaceType,
86-
#else
87-
Type serviceInterfaceType,
84+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicFields)]
8885
#endif
86+
Type serviceInterfaceType,
8987
bool useServiceUrl = false)
9088
{
9189
if (serviceInterfaceType == null)

src/LocalStack.Client/Utils/SessionReflection.cs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@ public IServiceMetadata ExtractServiceMetadata<TClient>() where TClient : Amazon
1414
[RequiresDynamicCode("Accesses private field 'serviceMetadata' with reflection; not safe for Native AOT."),
1515
RequiresUnreferencedCode("Reflection may break when IL trimming removes private members. We’re migrating to a source‑generated path in vNext.")]
1616
#endif
17-
public IServiceMetadata ExtractServiceMetadata(Type clientType)
17+
public IServiceMetadata ExtractServiceMetadata(
18+
#if NET8_0_OR_GREATER
19+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicFields)]
20+
#endif
21+
Type clientType
22+
)
1823
{
1924
if (clientType == null)
2025
{
@@ -41,7 +46,13 @@ public ClientConfig CreateClientConfig<TClient>() where TClient : AmazonServiceC
4146
[RequiresDynamicCode("Uses Activator.CreateInstance on derived ClientConfig types; not safe for Native AOT."),
4247
RequiresUnreferencedCode("Reflection may break when IL trimming removes private members. We’re migrating to a source‑generated path in vNext.")]
4348
#endif
44-
public ClientConfig CreateClientConfig(Type clientType)
49+
public ClientConfig CreateClientConfig(
50+
#if NET8_0_OR_GREATER
51+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]
52+
#endif
53+
Type clientType
54+
55+
)
4556
{
4657
if (clientType == null)
4758
{
@@ -58,7 +69,12 @@ public ClientConfig CreateClientConfig(Type clientType)
5869
[RequiresDynamicCode("Reflects over Config.RegionEndpoint property; not safe for Native AOT."),
5970
RequiresUnreferencedCode("Reflection may break when IL trimming removes private members. We’re migrating to a source‑generated path in vNext.")]
6071
#endif
61-
public void SetClientRegion(AmazonServiceClient amazonServiceClient, string systemName)
72+
public void SetClientRegion(
73+
#if NET8_0_OR_GREATER
74+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)]
75+
#endif
76+
AmazonServiceClient amazonServiceClient,
77+
string systemName)
6278
{
6379
if (amazonServiceClient == null)
6480
{
@@ -75,7 +91,12 @@ public void SetClientRegion(AmazonServiceClient amazonServiceClient, string syst
7591
[RequiresDynamicCode("Reflects over ForcePathStyle property; not safe for Native AOT."),
7692
RequiresUnreferencedCode("Reflection may break when IL trimming removes private members. We’re migrating to a source‑generated path in vNext.")]
7793
#endif
78-
public bool SetForcePathStyle(ClientConfig clientConfig, bool value = true)
94+
public bool SetForcePathStyle(
95+
#if NET8_0_OR_GREATER
96+
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)]
97+
#endif
98+
ClientConfig clientConfig,
99+
bool value = true)
79100
{
80101
if (clientConfig == null)
81102
{

0 commit comments

Comments
 (0)