Skip to content

Commit 6673566

Browse files
Release 4.14.0
- refactor: introduces AuthenticationClient and reorganise authentication standalone module
1 parent be3a12c commit 6673566

File tree

4 files changed

+98
-9
lines changed

4 files changed

+98
-9
lines changed

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<Project>
22
<PropertyGroup>
3-
<Version>4.13.1</Version>
3+
<Version>4.14.0</Version>
44
</PropertyGroup>
55
</Project>

src/CheckoutSdk/LogProvider.cs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,42 @@
22
using Microsoft.Extensions.Logging;
33
using Microsoft.Extensions.Logging.Abstractions;
44
using System;
5+
using System.Collections.Concurrent;
56

67
namespace Checkout
78
{
8-
99
public static class LogProvider
1010
{
11+
private static readonly object SyncRoot = new object();
1112
private static ILoggerFactory _loggerFactory = new LoggerFactory();
13+
private static readonly ConcurrentDictionary<Type, ILogger> Loggers = new ConcurrentDictionary<Type, ILogger>();
1214

1315
public static void SetLogFactory(ILoggerFactory factory)
1416
{
15-
_loggerFactory?.Dispose();
16-
_loggerFactory = factory ?? new LoggerFactory();
17+
lock (SyncRoot)
18+
{
19+
_loggerFactory?.Dispose();
20+
_loggerFactory = factory ?? new LoggerFactory();
21+
Loggers.Clear();
22+
}
1723
}
1824

1925
public static ILogger GetLogger(Type loggerType)
2026
{
21-
return loggerType is null ? NullLogger.Instance : _loggerFactory.CreateLogger(loggerType) ?? NullLogger.Instance;;
27+
if (loggerType == null)
28+
{
29+
return NullLogger.Instance;
30+
}
31+
32+
return Loggers.GetOrAdd(loggerType, type =>
33+
{
34+
lock (SyncRoot)
35+
{
36+
var name = type.FullName ?? type.Name;
37+
var logger = _loggerFactory.CreateLogger(name);
38+
return logger ?? NullLogger.Instance;
39+
}
40+
});
2241
}
2342
}
2443
}

test/CheckoutSdkTest/CheckoutSdkIntegrationTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ private class TestingClientFactory : IHttpClientFactory
7272
public HttpClient CreateClient()
7373
{
7474
var httpClient = new HttpClient(new CustomMessageHandler());
75-
httpClient.Timeout = TimeSpan.FromSeconds(2);
75+
httpClient.Timeout = TimeSpan.FromSeconds(3);
7676
return httpClient;
7777
}
7878
}

test/CheckoutSdkTest/LogProviderTest.cs

Lines changed: 73 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@
66

77
namespace Checkout
88
{
9+
[Collection("NonParallel")]
910
public sealed class LogProviderTests : IDisposable
1011
{
1112
private readonly ILoggerFactory _loggerFactory;
13+
14+
private static readonly object RandLock = new object();
15+
private static readonly Random Random = new Random();
1216

1317
public LogProviderTests()
1418
{
@@ -25,14 +29,20 @@ public void ShouldGetLoggerReturnsValidLogger()
2529
public async Task ShouldCreateASingleLoggerInstanceForMultipleConcurrentRequests()
2630
{
2731
LogProvider.SetLogFactory(_loggerFactory);
28-
Type[] loggerTypes = new[] { typeof(LogProviderTests), typeof(AnotherTestClass), typeof(NoInitializedType) };
32+
Type[] loggerTypes = { typeof(LogProviderTests), typeof(AnotherTestClass), typeof(NoInitializedType) };
33+
2934
Task<ILogger>[] createLoggerTasks = Enumerable.Range(1, 50)
3035
.Select(async index =>
3136
{
32-
int randomDelayMs = new Random().Next(1, 5);
33-
await Task.Delay(randomDelayMs);
37+
int delay;
38+
lock (RandLock)
39+
{
40+
delay = Random.Next(1, 5);
41+
}
42+
await Task.Delay(delay);
3443
return await Task.FromResult(LogProvider.GetLogger(loggerTypes[index % loggerTypes.Length]));
3544
}).ToArray();
45+
3646
ILogger[] loggers = await Task.WhenAll(createLoggerTasks);
3747
Assert.Equal(loggerTypes.Length, loggers.Distinct().Count());
3848
}
@@ -54,6 +64,66 @@ public void ShouldNotThrowExceptionWhenSetLogFactoryWithNullParameter()
5464
{
5565
Assert.Null(Record.Exception(() => LogProvider.SetLogFactory(null)));
5666
}
67+
68+
[Fact]
69+
public void ShouldReplaceLoggerFactoryCorrectly()
70+
{
71+
var loggerBefore = LogProvider.GetLogger(typeof(LogProviderTests));
72+
73+
var newFactory = LoggerFactory.Create(builder => builder.AddFilter(_ => false));
74+
LogProvider.SetLogFactory(newFactory);
75+
76+
var loggerAfter = LogProvider.GetLogger(typeof(LogProviderTests));
77+
78+
Assert.NotSame(loggerBefore, loggerAfter);
79+
}
80+
81+
[Fact]
82+
public void ShouldClearLoggersWhenFactoryChanges()
83+
{
84+
LogProvider.SetLogFactory(_loggerFactory);
85+
var logger1 = LogProvider.GetLogger(typeof(LogProviderTests));
86+
87+
var newFactory = new LoggerFactory();
88+
LogProvider.SetLogFactory(newFactory);
89+
var logger2 = LogProvider.GetLogger(typeof(LogProviderTests));
90+
91+
Assert.NotSame(logger1, logger2);
92+
}
93+
94+
[Fact]
95+
public void ShouldReturnSameLoggerOnMultipleCalls()
96+
{
97+
LogProvider.SetLogFactory(_loggerFactory);
98+
99+
var logger1 = LogProvider.GetLogger(typeof(LogProviderTests));
100+
var logger2 = LogProvider.GetLogger(typeof(LogProviderTests));
101+
102+
Assert.Same(logger1, logger2);
103+
}
104+
105+
[Fact]
106+
public async Task ShouldNotThrowWhenCallingSetLogFactoryConcurrently()
107+
{
108+
var tasks = Enumerable.Range(0, 10).Select(_ => Task.Run(() =>
109+
{
110+
LogProvider.SetLogFactory(new LoggerFactory());
111+
}));
112+
113+
var exception = await Record.ExceptionAsync(async () => await Task.WhenAll(tasks));
114+
115+
Assert.Null(exception);
116+
}
117+
118+
[Fact]
119+
public void ShouldAllowMultipleNullLoggerFactoryAssignments()
120+
{
121+
LogProvider.SetLogFactory(null);
122+
LogProvider.SetLogFactory(null);
123+
var logger = LogProvider.GetLogger(typeof(LogProviderTests));
124+
125+
Assert.NotNull(logger);
126+
}
57127

58128
public void Dispose()
59129
{

0 commit comments

Comments
 (0)