Skip to content

Commit 4e52f89

Browse files
committed
fixes #35
1 parent 5eac143 commit 4e52f89

24 files changed

+293
-703
lines changed

LocalStack.sln

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{152F3084
4141
EndProject
4242
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LocalStack.Build", "build\LocalStack.Build\LocalStack.Build.csproj", "{2CA18A71-CA83-4CC4-A777-AA4F56E4413F}"
4343
EndProject
44+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "common", "common", "{FF7B2686-CC4B-4B6C-B360-E487339DB210}"
45+
EndProject
46+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LocalStack.Tests.Common", "tests\common\LocalStack.Tests.Common\LocalStack.Tests.Common.csproj", "{7B896BF0-E9E1-44B7-9268-78A6B45CFE0D}"
47+
EndProject
4448
Global
4549
GlobalSection(SolutionConfigurationPlatforms) = preSolution
4650
Debug|Any CPU = Debug|Any CPU
@@ -91,6 +95,10 @@ Global
9195
{2CA18A71-CA83-4CC4-A777-AA4F56E4413F}.Debug|Any CPU.Build.0 = Debug|Any CPU
9296
{2CA18A71-CA83-4CC4-A777-AA4F56E4413F}.Release|Any CPU.ActiveCfg = Release|Any CPU
9397
{2CA18A71-CA83-4CC4-A777-AA4F56E4413F}.Release|Any CPU.Build.0 = Release|Any CPU
98+
{7B896BF0-E9E1-44B7-9268-78A6B45CFE0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
99+
{7B896BF0-E9E1-44B7-9268-78A6B45CFE0D}.Debug|Any CPU.Build.0 = Debug|Any CPU
100+
{7B896BF0-E9E1-44B7-9268-78A6B45CFE0D}.Release|Any CPU.ActiveCfg = Release|Any CPU
101+
{7B896BF0-E9E1-44B7-9268-78A6B45CFE0D}.Release|Any CPU.Build.0 = Release|Any CPU
94102
EndGlobalSection
95103
GlobalSection(SolutionProperties) = preSolution
96104
HideSolutionNode = FALSE
@@ -106,6 +114,8 @@ Global
106114
{A697D9A2-4DF7-4B4D-A189-EEC7F64B5609} = {3F0F4BAA-02EF-4008-9CF8-E73AA92D4664}
107115
{6CCFBCE0-C7C6-42A7-B39F-665B4C15C6FE} = {962A750E-8FE2-461F-B3FC-2B401309B5FD}
108116
{2CA18A71-CA83-4CC4-A777-AA4F56E4413F} = {152F3084-DC30-4A44-AEBC-E4C0EBFA0F4E}
117+
{FF7B2686-CC4B-4B6C-B360-E487339DB210} = {3F0F4BAA-02EF-4008-9CF8-E73AA92D4664}
118+
{7B896BF0-E9E1-44B7-9268-78A6B45CFE0D} = {FF7B2686-CC4B-4B6C-B360-E487339DB210}
109119
EndGlobalSection
110120
GlobalSection(ExtensibilityGlobals) = postSolution
111121
SolutionGuid = {E4925255-67AA-4095-816B-CC10A5490E71}

src/LocalStack.Client.Extensions/AwsClientFactoryWrapper.cs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
11
#pragma warning disable S3011 // We need to use reflection to access private fields for service metadata
22
#pragma warning disable CS8600,CS8603 // Not possible to get null value from this private field
3+
#pragma warning disable CA1802 // We need to use reflection to access private fields for service metadata
34
namespace LocalStack.Client.Extensions;
45

56
public sealed class AwsClientFactoryWrapper : IAwsClientFactoryWrapper
67
{
7-
private const string ClientFactoryFullName = "Amazon.Extensions.NETCore.Setup.ClientFactory";
8-
private const string CreateServiceClientMethodName = "CreateServiceClient";
8+
private static readonly string ClientFactoryFullName = "Amazon.Extensions.NETCore.Setup.ClientFactory";
9+
private static readonly string CreateServiceClientMethodName = "CreateServiceClient";
910

10-
public AmazonServiceClient CreateServiceClient<TClient>(IServiceProvider provider, AWSOptions awsOptions) where TClient : IAmazonService
11+
public AmazonServiceClient CreateServiceClient<TClient>(IServiceProvider provider, AWSOptions? awsOptions) where TClient : IAmazonService
1112
{
12-
if (awsOptions == null)
13-
{
14-
throw new ArgumentNullException(nameof(awsOptions));
15-
}
16-
1713
Type? clientFactoryType = typeof(ConfigurationException).Assembly.GetType(ClientFactoryFullName);
1814

1915
if (clientFactoryType == null)
@@ -31,7 +27,7 @@ public AmazonServiceClient CreateServiceClient<TClient>(IServiceProvider provide
3127

3228
Type clientType = typeof(TClient);
3329

34-
object clientFactory = constructorInfo.Invoke(new object[] { clientType, awsOptions });
30+
object clientFactory = constructorInfo.Invoke(new object[] { clientType, awsOptions! });
3531

3632
MethodInfo? methodInfo = clientFactory.GetType().GetMethod(CreateServiceClientMethodName, BindingFlags.NonPublic | BindingFlags.Instance);
3733

src/LocalStack.Client.Extensions/Contracts/IAwsClientFactoryWrapper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22

33
public interface IAwsClientFactoryWrapper
44
{
5-
AmazonServiceClient CreateServiceClient<TClient>(IServiceProvider provider, AWSOptions awsOptions) where TClient : IAmazonService;
5+
AmazonServiceClient CreateServiceClient<TClient>(IServiceProvider provider, AWSOptions? awsOptions) where TClient : IAmazonService;
66
}

src/LocalStack.Client.Extensions/README.md

Lines changed: 71 additions & 330 deletions
Large diffs are not rendered by default.

src/LocalStack.Client/README.md

Lines changed: 71 additions & 330 deletions
Large diffs are not rendered by default.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
namespace LocalStack.Client.Extensions.Tests;
2+
3+
public class AwsClientFactoryWrapperTests
4+
{
5+
private readonly IAwsClientFactoryWrapper _awsClientFactoryWrapper;
6+
private readonly Mock<IServiceProvider> _mockServiceProvider;
7+
private readonly AWSOptions _awsOptions;
8+
9+
public AwsClientFactoryWrapperTests()
10+
{
11+
_awsClientFactoryWrapper = new AwsClientFactoryWrapper();
12+
_mockServiceProvider = new Mock<IServiceProvider>();
13+
_awsOptions = new AWSOptions();
14+
}
15+
16+
[Fact]
17+
public void CreateServiceClient_Should_Throw_LocalStackClientConfigurationException_When_ClientFactoryType_Is_Null()
18+
{
19+
Type type = _awsClientFactoryWrapper.GetType();
20+
const BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Static;
21+
22+
FieldInfo? clientFactoryFullNameField = type.GetField("ClientFactoryFullName", bindingFlags);
23+
FieldInfo? createServiceClientMethodNameFieldInfo = type.GetField("CreateServiceClientMethodName", bindingFlags);
24+
25+
Assert.NotNull(clientFactoryFullNameField);
26+
Assert.NotNull(createServiceClientMethodNameFieldInfo);
27+
28+
SetPrivateReadonlyField(clientFactoryFullNameField, "NonExistingType");
29+
SetPrivateReadonlyField(createServiceClientMethodNameFieldInfo, "NonExistingMethod");
30+
31+
Assert.Throws<LocalStackClientConfigurationException>(
32+
() => _awsClientFactoryWrapper.CreateServiceClient<MockAmazonServiceClient>(_mockServiceProvider.Object, _awsOptions));
33+
}
34+
35+
[Fact]
36+
public void CreateServiceClient_Should_Create_Client_When_UseLocalStack_False()
37+
{
38+
ConfigurationBuilder configurationBuilder = new();
39+
configurationBuilder.AddInMemoryCollection(new KeyValuePair<string, string?>[] { new("LocalStack:UseLocalStack", "false") });
40+
IConfigurationRoot configurationRoot = configurationBuilder.Build();
41+
42+
ServiceCollection serviceCollection = new();
43+
serviceCollection.AddLocalStack(configurationRoot);
44+
serviceCollection.AddAWSServiceLocalStack<IAmazonS3>();
45+
ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
46+
47+
var requiredService = serviceProvider.GetRequiredService<IAmazonS3>();
48+
49+
Assert.NotNull(requiredService);
50+
}
51+
52+
private static void SetPrivateReadonlyField(FieldInfo field, string value)
53+
{
54+
var method = new DynamicMethod("SetReadOnlyField", null, new[] { typeof(object), typeof(object) }, typeof(AwsClientFactoryWrapper), true);
55+
var il = method.GetILGenerator();
56+
57+
il.Emit(OpCodes.Ldarg_0);
58+
il.Emit(OpCodes.Castclass, field.DeclaringType!);
59+
il.Emit(OpCodes.Ldarg_1);
60+
il.Emit(OpCodes.Stfld, field);
61+
il.Emit(OpCodes.Ret);
62+
63+
method.Invoke(null, new object[] { null!, value });
64+
}
65+
}

tests/LocalStack.Client.Extensions.Tests/GlobalUsings.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
global using System;
22
global using System.Collections.Generic;
33
global using System.Globalization;
4+
global using System.Reflection;
5+
global using System.Reflection.Emit;
46
global using System.Text.Json;
57

68
global using Microsoft.Extensions.Configuration;
@@ -11,14 +13,16 @@
1113
global using Amazon;
1214
global using Amazon.Extensions.NETCore.Setup;
1315
global using Amazon.Runtime;
16+
global using Amazon.S3;
1417

1518
global using LocalStack.Client.Contracts;
1619
global using LocalStack.Client.Extensions.Contracts;
20+
global using LocalStack.Client.Extensions.Exceptions;
1721
global using LocalStack.Client.Extensions.Tests.Extensions;
1822
global using LocalStack.Client.Options;
19-
global using LocalStack.Client.Tests.Mocks.MockServiceClients;
2023
global using LocalStack.Client.Utils;
2124
global using LocalStack.Client.Models;
25+
global using LocalStack.Tests.Common.Mocks.MockServiceClients;
2226

2327
global using Moq;
2428
global using Xunit;

tests/LocalStack.Client.Extensions.Tests/LocalStack.Client.Extensions.Tests.csproj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
</PropertyGroup>
77

88
<ItemGroup>
9-
<PackageReference Include="AWSSDK.Core" />
9+
<PackageReference Include="AWSSDK.S3" />
1010
<PackageReference Include="Microsoft.Extensions.Configuration" />
1111
<PackageReference Include="Microsoft.Extensions.DependencyInjection" />
1212

@@ -30,4 +30,6 @@
3030
<ProjectReference Include="..\LocalStack.Client.Tests\LocalStack.Client.Tests.csproj" />
3131
</ItemGroup>
3232

33+
34+
3335
</Project>

tests/LocalStack.Client.Tests/GlobalUsings.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,13 @@
88
global using Amazon;
99
global using Amazon.Runtime;
1010
global using Amazon.Runtime.Internal;
11-
global using Amazon.Runtime.Internal.Auth;
12-
global using Amazon.Util.Internal;
1311

14-
global using LocalStack.Client.Contracts;
1512
global using LocalStack.Client.Enums;
1613
global using LocalStack.Client.Exceptions;
1714
global using LocalStack.Client.Models;
1815
global using LocalStack.Client.Options;
19-
global using LocalStack.Client.Tests.Mocks;
20-
global using LocalStack.Client.Tests.Mocks.MockServiceClients;
16+
global using LocalStack.Tests.Common.Mocks;
17+
global using LocalStack.Tests.Common.Mocks.MockServiceClients;
2118
global using LocalStack.Client.Utils;
2219

2320
global using Moq;

tests/LocalStack.Client.Tests/LocalStack.Client.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,6 @@
2727

2828
<ItemGroup>
2929
<ProjectReference Include="..\..\src\LocalStack.Client\LocalStack.Client.csproj" />
30+
<ProjectReference Include="..\common\LocalStack.Tests.Common\LocalStack.Tests.Common.csproj" />
3031
</ItemGroup>
3132
</Project>

0 commit comments

Comments
 (0)