Skip to content

Instantly share code, notes, and snippets.

@dcomartin
Created April 3, 2025 20:22
public class SignUp
{
private readonly DbContext _dbContext;
private readonly Email _email;
public SignUp(DbContext dbContext, Email email)
{
_dbContext = dbContext;
_email = email;
}
public async Task Handle(SignUpRequest request)
{
ValidateUsername(request);
ValidateExistingUser(request);
var user = new User(request.Username, request.Email);
var channels = request.Channels;
FilterAgeRestrictedChannels(request, channels);
user.Channels.AddRange(channels);
_dbContext.Users.Add(user);
_dbContext.Save();
await SendEmail(user);
}
private async Task SendEmail(User user)
{
var email = new MailMessage("derek@codeopinion.com", user.Email);
email.Subject = "Welcome!";
email.Body = "Activate your account [link goes here]";
await _email.Send(email);
}
private void ValidateExistingUser(SignUpRequest request)
{
var existingUser = _dbContext.Users.SingleOrDefault(x => x.Username == request.Username);
if (ExistingSignUpNotYetActivated(request, existingUser))
{
throw new InvalidOperationException("You've already registered. Please active your account.");
}
if (existingUser != null)
{
throw new InvalidOperationException("Username is already registered.");
}
}
private void FilterAgeRestrictedChannels(SignUpRequest request, List<int> channels)
{
var now = DateTime.UtcNow;
if (request.Birthday.AddYears(18) <= now)
{
var kidsAllowedChannels = _dbContext.Channels
.Where(x => request.Channels.Contains(x.ChannelId) && x.Age18Required == false)
.Select(x => x.ChannelId)
.ToArray();
channels.Clear();
channels.AddRange(kidsAllowedChannels);
}
}
private static void ValidateUsername(SignUpRequest request)
{
if (string.IsNullOrWhiteSpace(request.Username))
{
throw new InvalidOperationException("Username is required.");
}
}
private static bool ExistingSignUpNotYetActivated(SignUpRequest request, User? existingUser)
{
return existingUser is { ActivationDate: null } && existingUser.Email.Equals(request.Email, StringComparison.InvariantCultureIgnoreCase);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment