Add users with in-memory repository

This commit is contained in:
Sergey Nazarov 2024-03-23 09:59:37 +04:00
parent fe9edd891b
commit a0626b25d7
10 changed files with 30 additions and 22 deletions

View File

@ -1,4 +1,4 @@
namespace Nocr.Users.Api.Contracts.Users; namespace Nocr.Users.Api.Contracts.Users.Dto;
public sealed class UserData public sealed class UserData
{ {

View File

@ -1,5 +1,6 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Nocr.Users.AppServices.Users; using Nocr.Users.AppServices.Users.Repositories;
using Nocr.Users.AppServices.Users.Services;
namespace Nocr.Users.AppServices; namespace Nocr.Users.AppServices;
@ -11,7 +12,7 @@ public static class ServiceCollectionExtensions
throw new ArgumentNullException(nameof(services)); throw new ArgumentNullException(nameof(services));
// Add registrations here // Add registrations here
services.AddScoped<IUsersRepository, InMemoryUsersRepository>(); services.AddSingleton<IUsersRepository, InMemoryUsersRepository>();
services.AddScoped<IUsersService, UsersService>(); services.AddScoped<IUsersService, UsersService>();
return services; return services;

View File

@ -1,4 +1,4 @@
namespace Nocr.Users.AppServices.Users; namespace Nocr.Users.AppServices.Users.Repositories;
public interface IUsersRepository public interface IUsersRepository
{ {

View File

@ -1,4 +1,4 @@
namespace Nocr.Users.AppServices.Users; namespace Nocr.Users.AppServices.Users.Repositories;
public sealed class InMemoryUsersRepository : IUsersRepository public sealed class InMemoryUsersRepository : IUsersRepository
{ {

View File

@ -1,11 +1,11 @@
using Nocr.Users.Api.Contracts.Users; using Nocr.Users.Api.Contracts.Users.Dto;
namespace Nocr.Users.AppServices.Users; namespace Nocr.Users.AppServices.Users.Services;
public interface IUsersService public interface IUsersService
{ {
Task<long> Create(string username, string? telegramUsername, string? email, long? telegramId, Task<long> Create(string username, string? telegramUsername, string? email, long? telegramId,
CancellationToken cancellationToken = default); CancellationToken cancellationToken = default);
Task<UserData?> GetUserById(long id, CancellationToken cancellationToken = default); Task<UserData?> GetById(long id, CancellationToken cancellationToken = default);
} }

View File

@ -1,6 +1,7 @@
using Nocr.Users.Api.Contracts.Users; using Nocr.Users.Api.Contracts.Users.Dto;
using Nocr.Users.AppServices.Users.Repositories;
namespace Nocr.Users.AppServices.Users; namespace Nocr.Users.AppServices.Users.Services;
public sealed class UsersService : IUsersService public sealed class UsersService : IUsersService
{ {
@ -31,7 +32,7 @@ public sealed class UsersService : IUsersService
return await _repository.Create(user, cancellationToken); return await _repository.Create(user, cancellationToken);
} }
public async Task<UserData?> GetUserById(long id, CancellationToken cancellationToken = default) public async Task<UserData?> GetById(long id, CancellationToken cancellationToken = default)
{ {
var user = await _repository.GetUserById(id, cancellationToken); var user = await _repository.GetUserById(id, cancellationToken);
if (user == null) if (user == null)

View File

@ -6,15 +6,20 @@ public sealed class User
public string Username { get; private set; } public string Username { get; private set; }
private List<UserIdentity> _identities = new List<UserIdentity>(); private readonly List<UserIdentity> _identities = new();
public IReadOnlyCollection<UserIdentity> Identities => _identities; public IReadOnlyCollection<UserIdentity> Identities => _identities;
private User(string username, params UserIdentity[] identities) private User(string username, params UserIdentity[] identities)
{ {
Username = username; Username = username;
// TODO: Check that there is no repeating identity types // TODO: Check that there is no repeating identity types
if (identities.GroupBy(x => x.Type).SelectMany(g => g.Skip(1)).Any())
{
throw new InvalidOperationException($"All identities should be unique by {nameof(UserIdentity.Type)}");
}
_identities.AddRange(identities); _identities.AddRange(identities);
} }

View File

@ -6,15 +6,15 @@ public sealed class UserIdentity
public string Identity { get; private set; } public string Identity { get; private set; }
public UserIdentityType IdentityType { get; private set; } public UserIdentityType Type { get; private set; }
private UserIdentity(string identity, UserIdentityType identityType) private UserIdentity(string identity, UserIdentityType type)
{ {
if (string.IsNullOrWhiteSpace(identity)) if (string.IsNullOrWhiteSpace(identity))
throw new ArgumentNullException(nameof(identity)); throw new ArgumentNullException(nameof(identity));
Identity = identity; Identity = identity;
IdentityType = identityType; Type = type;
} }
public static UserIdentity TelegramId(string identity) public static UserIdentity TelegramId(string identity)

View File

@ -1,10 +1,9 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Nocr.Users.Api.Contracts; using Nocr.Users.Api.Contracts;
using Nocr.Users.Api.Contracts.Users;
using Nocr.Users.Api.Contracts.Users.Dto; using Nocr.Users.Api.Contracts.Users.Dto;
using Nocr.Users.AppServices.Users; using Nocr.Users.AppServices.Users.Services;
namespace Nocr.Users.Host; namespace Nocr.Users.Host.Controllers;
[ApiController] [ApiController]
[Route(WebRoutes.Users.Path)] [Route(WebRoutes.Users.Path)]
@ -20,11 +19,13 @@ public class UsersController : ControllerBase
[HttpPost] [HttpPost]
public Task<long> Create([FromBody] CreateUserRequest request, CancellationToken cancellationToken = default) public Task<long> Create([FromBody] CreateUserRequest request, CancellationToken cancellationToken = default)
{ {
return _usersService.Create(request.Username, request.TelegramUsername, request.Email, request.TelegramId, cancellationToken); return _usersService.Create(request.Username, request.TelegramUsername, request.Email, request.TelegramId,
cancellationToken);
} }
[HttpGet("{id}")] [HttpGet("{id}")]
public Task<UserData?> GetById([FromRoute] long id, CancellationToken cancellationToken = default) public Task<UserData?> GetById([FromRoute] long id, CancellationToken cancellationToken = default)
{ {
return _usersService.GetUserById(id, cancellationToken); return _usersService.GetById(id, cancellationToken);
} }
} }

View File

@ -12,7 +12,7 @@ public class HostBuilderFactory<TStartup> where TStartup : class
if (!string.IsNullOrWhiteSpace(baseDirectory)) if (!string.IsNullOrWhiteSpace(baseDirectory))
configurationBuilder.SetBasePath(baseDirectory); configurationBuilder.SetBasePath(baseDirectory);
configurationBuilder.AddJsonFile("appsettings.protected.json", false); configurationBuilder.AddJsonFile("appsettings.protected.json", true);
}) })
.ConfigureWebHostDefaults(host => { host.UseStartup<TStartup>(); }) .ConfigureWebHostDefaults(host => { host.UseStartup<TStartup>(); })
.UseSerilog((ctx, logBuilder) => .UseSerilog((ctx, logBuilder) =>