Skip to content

Commit 6a17814

Browse files
committed
chore: Cleanup Access Layer
1 parent 6d07b8e commit 6a17814

25 files changed

+107
-150
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ Prefix your items with `(Template)` if the change is about the template and not
88
## 3.10.X
99
- Added Dependency Injection validation in the development environment.
1010
- Cleaned up the persistence configuration files (removed unused parameters and updated documentation).
11+
- Updated Contributing documentation.
12+
- Cleanup the 'Access' layer's code (renamed repositories into API clients, removed unused namespaces, and sealed some classes).
1113

1214
## 3.9.X
1315
- Removed unnecessary `IsExternalInit.cs` files.
@@ -20,7 +22,6 @@ Prefix your items with `(Template)` if the change is about the template and not
2022
- Optimized the .NET workloads install process.
2123
- Fixed the iOS application icon size.
2224
- Added VM Disposal in Functional Tests.
23-
- Updated Contributing documentation.
2425

2526
## 3.8.X
2627
- Updated from .NET 8 to .NET 9.

src/app/ApplicationTemplate.Access/ApiClients/Authentication/AuthenticationApiClientMock.cs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,30 +45,26 @@ public async Task<AuthenticationData> RefreshToken(CancellationToken ct, Authent
4545

4646
await SimulateDelay(ct);
4747

48-
return CreateAuthenticationData(unauthorizedToken.AccessTokenPayload);
48+
return CreateAuthenticationData(unauthorizedToken.AccessToken.Payload);
4949
}
5050

51-
private AuthenticationData CreateAuthenticationData(AuthenticationToken token = null, TimeSpan? timeToLive = null)
51+
private AuthenticationData CreateAuthenticationData(AuthenticationToken token = null)
5252
{
53-
var encodedJwt = CreateJsonWebToken(token, timeToLive);
54-
var jwt = new JwtData<AuthenticationToken>(encodedJwt, _serializerOptions);
53+
var encodedJwt = CreateJsonWebToken(token);
5554

5655
return new AuthenticationData()
5756
{
58-
AccessToken = jwt.Token,
57+
AccessToken = new JwtData<AuthenticationToken>(encodedJwt, _serializerOptions),
5958
RefreshToken = Guid.NewGuid().ToString(format: null, CultureInfo.InvariantCulture),
60-
Expiration = jwt.Payload.Expiration,
6159
};
6260
}
6361

64-
private string CreateJsonWebToken(AuthenticationToken token = null, TimeSpan? timeToLive = null)
62+
private string CreateJsonWebToken(AuthenticationToken token = null)
6563
{
6664
const string header = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"; // alg=HS256, type=JWT
6765
const string signature = "QWqnPP8W6ymexz74P6quP-oG-wxr7vMGqrEL8y_tV6M"; // dummy stuff
6866

69-
var now = DateTimeOffset.Now;
70-
71-
token = token ?? new AuthenticationToken(default, DateTimeOffset.MinValue, DateTimeOffset.MinValue);
67+
token ??= new AuthenticationToken(default, DateTimeOffset.MinValue, DateTimeOffset.MinValue);
7268

7369
string payload;
7470
using (var stream = new MemoryStream())

src/app/ApplicationTemplate.Access/ApiClients/Authentication/AuthenticationData.cs

Lines changed: 0 additions & 37 deletions
This file was deleted.
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System;
2+
using System.Text.Json.Serialization;
3+
using MallardMessageHandlers;
4+
5+
namespace ApplicationTemplate.DataAccess;
6+
7+
public sealed class AuthenticationData : IAuthenticationToken
8+
{
9+
[JsonPropertyName("access_token")]
10+
[JsonConverter(typeof(JwtDataJsonConverter<AuthenticationToken>))]
11+
public JwtData<AuthenticationToken> AccessToken { get; init; }
12+
13+
[JsonPropertyName("refresh_token")]
14+
public string RefreshToken { get; init; }
15+
16+
[JsonIgnore]
17+
string IAuthenticationToken.AccessToken => AccessToken?.Token;
18+
19+
[JsonIgnore]
20+
public bool CanBeRefreshed => !string.IsNullOrEmpty(RefreshToken);
21+
22+
[JsonIgnore]
23+
public string Email => AccessToken?.Payload?.Email;
24+
25+
[JsonIgnore]
26+
public DateTimeOffset? Expiration => AccessToken?.Payload?.Expiration;
27+
}
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
using System;
2-
using System.Text.Json;
32
using System.Text.Json.Serialization;
43

54
namespace ApplicationTemplate.DataAccess;
65

7-
public class AuthenticationToken
6+
public sealed class AuthenticationToken
87
{
9-
public AuthenticationToken() { }
10-
118
public AuthenticationToken(string email, DateTimeOffset expiration, DateTimeOffset issuedAt)
129
{
1310
Email = email;
@@ -16,13 +13,13 @@ public AuthenticationToken(string email, DateTimeOffset expiration, DateTimeOffs
1613
}
1714

1815
[JsonPropertyName("unique_name")]
19-
public string Email { get; set; }
16+
public string Email { get; init; }
2017

2118
[JsonPropertyName("exp")]
2219
[JsonConverter(typeof(UnixTimestampJsonConverter))]
23-
public DateTimeOffset Expiration { get; set; }
20+
public DateTimeOffset Expiration { get; init; }
2421

2522
[JsonPropertyName("iat")]
2623
[JsonConverter(typeof(UnixTimestampJsonConverter))]
27-
public DateTimeOffset IssuedAt { get; set; }
24+
public DateTimeOffset IssuedAt { get; init; }
2825
}

src/app/ApplicationTemplate.Access/ApiClients/Authentication/IAuthenticationApiClient.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Text;
4-
using System.Threading;
1+
using System.Threading;
52
using System.Threading.Tasks;
63

74
namespace ApplicationTemplate.DataAccess;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
namespace ApplicationTemplate.DataAccess;
2+
3+
public sealed class ErrorData
4+
{
5+
}

src/app/ApplicationTemplate.Access/ApiClients/Posts/PostData.cs renamed to src/app/ApplicationTemplate.Access/ApiClients/Posts/Data/PostData.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Text;
4-
using System.Text.Json.Serialization;
1+
using System.Text.Json.Serialization;
52

63
namespace ApplicationTemplate.DataAccess;
74

8-
public record PostData
5+
public sealed record PostData
96
{
107
public PostData(long id, string title, string body, long userIdentifier)
118
{
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace ApplicationTemplate.DataAccess;
2+
3+
public sealed class PostErrorResponse
4+
{
5+
public PostData Data { get; }
6+
7+
public ErrorData Error { get; }
8+
}

src/app/ApplicationTemplate.Access/ApiClients/Posts/ErrorData.cs

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/app/ApplicationTemplate.Access/ApiClients/Posts/IPostRepository.cs renamed to src/app/ApplicationTemplate.Access/ApiClients/Posts/IPostsApiClient.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Text;
4-
using System.Threading;
1+
using System.Threading;
52
using System.Threading.Tasks;
63
using Refit;
74

@@ -11,7 +8,7 @@ namespace ApplicationTemplate.DataAccess;
118
/// Provides access to the posts API.
129
/// </summary>
1310
[Headers("Authorization: Bearer")]
14-
public interface IPostsRepository
11+
public interface IPostsApiClient
1512
{
1613
/// <summary>
1714
/// Gets the list of all posts.

src/app/ApplicationTemplate.Access/ApiClients/Posts/PostErrorResponse.cs

Lines changed: 0 additions & 12 deletions
This file was deleted.

src/app/ApplicationTemplate.Access/ApiClients/Posts/PostRepositoryException.cs

Lines changed: 0 additions & 26 deletions
This file was deleted.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using System;
2+
3+
namespace ApplicationTemplate.DataAccess;
4+
5+
public sealed class PostsApiClientException : Exception
6+
{
7+
public PostsApiClientException()
8+
{
9+
}
10+
11+
public PostsApiClientException(string message)
12+
: base(message)
13+
{
14+
}
15+
16+
public PostsApiClientException(string message, Exception innerException)
17+
: base(message, innerException)
18+
{
19+
}
20+
21+
public PostsApiClientException(PostErrorResponse errorResponse)
22+
{
23+
}
24+
}

src/app/ApplicationTemplate.Access/ApiClients/Posts/PostsRepositoryMock.cs renamed to src/app/ApplicationTemplate.Access/ApiClients/Posts/PostsApiClientMock.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Text;
4-
using System.Text.Json;
1+
using System.Text.Json;
52
using System.Threading;
63
using System.Threading.Tasks;
74
using Refit;
85

96
namespace ApplicationTemplate.DataAccess;
107

11-
public class PostsRepositoryMock : BaseMock, IPostsRepository
8+
public sealed class PostsApiClientMock : BaseMock, IPostsApiClient
129
{
13-
public PostsRepositoryMock(JsonSerializerOptions serializerOptions)
10+
public PostsApiClientMock(JsonSerializerOptions serializerOptions)
1411
: base(serializerOptions)
1512
{
1613
}

src/app/ApplicationTemplate.Access/ApiClients/UserProfile/IUserProfileRepository.cs renamed to src/app/ApplicationTemplate.Access/ApiClients/UserProfile/IUserProfileApiClient.cs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Text;
4-
using System.Threading;
1+
using System.Threading;
52
using System.Threading.Tasks;
63
using Refit;
74

@@ -11,7 +8,7 @@ namespace ApplicationTemplate.DataAccess;
118
/// Provides access to the user profile API.
129
/// </summary>
1310
[Headers("Authorization: Bearer")]
14-
public interface IUserProfileRepository
11+
public interface IUserProfileApiClient
1512
{
1613
/// <summary>
1714
/// Returns the current user profile.

src/app/ApplicationTemplate.Access/ApiClients/UserProfile/UserProfileRepositoryMock.cs renamed to src/app/ApplicationTemplate.Access/ApiClients/UserProfile/UserProfileApiClientMock.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
using System;
2-
using System.Collections.Generic;
3-
using System.Text;
42
using System.Text.Json;
53
using System.Threading;
64
using System.Threading.Tasks;
@@ -9,12 +7,12 @@
97

108
namespace ApplicationTemplate.DataAccess;
119

12-
public class UserProfileRepositoryMock : BaseMock, IUserProfileRepository
10+
public sealed class UserProfileApiClientMock : BaseMock, IUserProfileApiClient
1311
{
1412
private readonly IAuthenticationTokenProvider<AuthenticationData> _tokenProvider;
1513
private readonly IOptionsMonitor<MockOptions> _mockOptionsMonitor;
1614

17-
public UserProfileRepositoryMock(
15+
public UserProfileApiClientMock(
1816
IAuthenticationTokenProvider<AuthenticationData> tokenProvider,
1917
JsonSerializerOptions serializerOptions,
2018
IOptionsMonitor<MockOptions> mockOptionsMonitor)

src/app/ApplicationTemplate.Access/ApplicationTemplate.Access.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010

1111
<ItemGroup>
1212
<EmbeddedResource Include="ApiClients\DadJokes\DadJokesApiClientMock.FetchData.json" />
13-
<EmbeddedResource Include="ApiClients\Posts\PostsRepositoryMock.GetAll.json" />
14-
<EmbeddedResource Include="ApiClients\UserProfile\UserProfileRepositoryMock.Get.json" />
13+
<EmbeddedResource Include="ApiClients\Posts\PostsApiClientMock.GetAll.json" />
14+
<EmbeddedResource Include="ApiClients\UserProfile\UserProfileApiClientMock.Get.json" />
1515
</ItemGroup>
1616

1717
<ItemGroup>

src/app/ApplicationTemplate.Business/Posts/PostService.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ namespace ApplicationTemplate.Business;
88

99
public partial class PostService : IPostService
1010
{
11-
private readonly IPostsRepository _postsRepository;
11+
private readonly IPostsApiClient _postsRepository;
1212

13-
public PostService(IPostsRepository postsRepository)
13+
public PostService(IPostsApiClient postsRepository)
1414
{
1515
_postsRepository = postsRepository;
1616
}

src/app/ApplicationTemplate.Business/UserProfile/UserProfileService.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ namespace ApplicationTemplate.Business;
1212

1313
public partial class UserProfileService : IUserProfileService
1414
{
15-
private readonly IUserProfileRepository _profileRepository;
15+
private readonly IUserProfileApiClient _profileRepository;
1616

17-
public UserProfileService(IUserProfileRepository profileRepository)
17+
public UserProfileService(IUserProfileApiClient profileRepository)
1818
{
1919
_profileRepository = profileRepository ?? throw new ArgumentNullException(nameof(profileRepository));
2020
}

src/app/ApplicationTemplate.Presentation/Configuration/ApiConfiguration.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public static IServiceCollection AddApi(this IServiceCollection services, IConfi
5353
private static IServiceCollection AddUserProfile(this IServiceCollection services)
5454
{
5555
// This one doesn't have an actual remote API yet. It's always a mock implementation.
56-
return services.AddSingleton<IUserProfileRepository, UserProfileRepositoryMock>();
56+
return services.AddSingleton<IUserProfileApiClient, UserProfileApiClientMock>();
5757
}
5858

5959
private static IServiceCollection AddMinimumVersion(this IServiceCollection services)
@@ -79,10 +79,10 @@ private static IServiceCollection AddPosts(this IServiceCollection services, ICo
7979
return services
8080
.AddSingleton<IErrorResponseInterpreter<PostErrorResponse>>(s => new ErrorResponseInterpreter<PostErrorResponse>(
8181
(request, response, deserializedResponse) => deserializedResponse.Error != null,
82-
(request, response, deserializedResponse) => new PostRepositoryException(deserializedResponse)
82+
(request, response, deserializedResponse) => new PostsApiClientException(deserializedResponse)
8383
))
8484
.AddTransient<ExceptionInterpreterHandler<PostErrorResponse>>()
85-
.AddApiClient<IPostsRepository, PostsRepositoryMock>(configuration, "PostApiClient", b => b
85+
.AddApiClient<IPostsApiClient, PostsApiClientMock>(configuration, "PostApiClient", b => b
8686
.AddHttpMessageHandler<ExceptionInterpreterHandler<PostErrorResponse>>()
8787
.AddHttpMessageHandler<AuthenticationTokenHandler<AuthenticationData>>()
8888
);

0 commit comments

Comments
 (0)