Do you recommend adding a layer of abstraction on top of EF Core for example we have an API controller responsible for authentication do I just call EF Core methods directly in the controller or do I add a service that manages all the methods needed for authentication? An authService that uses EF Core methods or go further and make both a user repository and an authService that uses the user repository, I am honestly so confused to how I would go about this.
This is an example of how I would implement this:
[HttpPost("sign-up")]
[AllowAnonymous]
public async Task<IActionResult> RegisterUser([FromBody] EssentialSignUpCredentials registerCredentials)
{
var clientEmail = registerCredentials.email;
var clientUserName = registerCredentials.userName;
var ipAddress = HttpContext.Connection.RemoteIpAddress?.MapToIPv4();
var response=await authService.SignUpAsync(registerCredentials.email, registerCredentials.userName, ipAddress);
return response.Match<IActionResult>(Ok, BadRequest);
}
public class AuthService(IJwtTokenService jwtTokenService, IUserService userService, DBContext dbContext) : IAuthService
{
public async Task<Result<SignInResponse>> SignInAsync()
{
throw new NotImplementedException();
}
public async Task<Result> SignUpAsync(string email, string userName, IPAddress ipAddress)
{
await using var transaction = await dbContext.Database.BeginTransactionAsync();
var response = await userService.CreateUserAsync(email, userName, ipAddress);
return await response.MatchAsync<Result, User>(async success =>
{
var rolesResponse = await userService.AddRolesToUserAsync(success.Data);
if (!rolesResponse.isSuccess)
return Result.Failure(rolesResponse.FailureValue.errors.ToArray(),
rolesResponse.FailureValue.StatusCode);
await transaction.CommitAsync();
return Result.Success();
}, failure => Result.Failure(response.FailureValue.errors.ToArray(), response.FailureValue.StatusCode));
}
}
Do you recommend this sort of approach? Is the transaction in authorization service considered best practice? Is this considered clean code?