Skip to content

Instantly share code, notes, and snippets.

@ahmetkucukoglu
Created December 17, 2024 12:15
Show Gist options
  • Save ahmetkucukoglu/4f61a3acae040c3c556739d165a0a779 to your computer and use it in GitHub Desktop.
Save ahmetkucukoglu/4f61a3acae040c3c556739d165a0a779 to your computer and use it in GitHub Desktop.
Persistence Ignorance - Voting Repository
using Microsoft.EntityFrameworkCore;
using PersistenceIgnorance.Domain.Voting;
using PersistenceIgnorance.Domain.Voting.Events;
using PersistenceIgnorance.Infrastructure.Persistence.Entities;
namespace PersistenceIgnorance.Infrastructure.Persistence.Repositories;
public class VotingRepository(VotingDbContext dbContext)
{
public async Task<VotingEntity> GetAsync(int id)
{
var voting = await dbContext.Votings
.AsNoTracking()
.Include(v => v.Voters)
.FirstOrDefaultAsync(v => v.Id == id);
if (voting == null)
throw new InvalidOperationException("The voting has not found.");
return voting;
}
public async Task<Voting> GetAggregateAsync(int id)
{
var voting = await dbContext.Votings
.AsNoTracking()
.Include(v => v.Voters)
.FirstOrDefaultAsync(v => v.Id == id);
if (voting == null)
throw new InvalidOperationException("The voting has not found.");
var voters = voting.Voters
.Select(v => new Voter(v.IdentityNumber, v.Status))
.ToList();
return new Voting(voters, voting.StartedAt.HasValue, voting.ClosedAt.HasValue);
}
public async Task<int> CreateAsync(Voting voting)
{
var votingEntity = new VotingEntity();
foreach (var @event in voting.GetEvents)
{
HandleEvent(@event, votingEntity);
}
dbContext.Votings.Add(votingEntity);
await dbContext.SaveChangesAsync();
return votingEntity.Id;
}
public async Task UpdateAsync(int id, Voting voting)
{
var votingEntity = dbContext.Votings
.Include(v => v.Voters)
.FirstOrDefault(v => v.Id == id);
if (votingEntity == null)
throw new InvalidOperationException("The voting has not found.");
foreach (var @event in voting.GetEvents)
{
HandleEvent(@event, votingEntity);
}
await dbContext.SaveChangesAsync();
}
private void HandleEvent(object @event, VotingEntity voting)
{
switch (@event)
{
case VoterAdded voterAdded:
HandleVoterAdded(voterAdded, voting);
break;
case VoterRemoved voterRemoved:
HandleVoterRemoved(voterRemoved, voting);
break;
case VoterApproved voterApproved:
HandleVoterApproved(voterApproved, voting);
break;
case VoterRejected voterRejected:
HandleVoterRejected(voterRejected, voting);
break;
case VotingStarted votingStarted:
HandleVotingStarted(votingStarted, voting);
break;
case VotingClosed votingClosed:
HandleVotingClosed(votingClosed, voting);
break;
}
}
private void HandleVoterAdded(VoterAdded approverAdded, VotingEntity voting)
{
voting.Voters.Add(new VoterEntity
{
IdentityNumber = approverAdded.IdentityNumber,
Status = VotingStatus.Waiting
});
voting.TotalVoterCount++;
}
private void HandleVoterRemoved(VoterRemoved voterRemoved, VotingEntity voting)
{
var voter = voting.Voters.FirstOrDefault(v => v.IdentityNumber == voterRemoved.IdentityNumber);
if (voter == null) return;
voting.Voters.Remove(voter);
voting.TotalVoterCount--;
}
private void HandleVoterApproved(VoterApproved voterApproved, VotingEntity voting)
{
var voter = voting.Voters.FirstOrDefault(v => v.IdentityNumber == voterApproved.IdentityNumber);
if (voter == null) return;
voter.Status = VotingStatus.Approved;
voter.VotedAt = voterApproved.ApprovedAt;
voting.TotalApprovedCount++;
}
private void HandleVoterRejected(VoterRejected voterRejected, VotingEntity voting)
{
var voter = voting.Voters.FirstOrDefault(v => v.IdentityNumber == voterRejected.IdentityNumber);
if (voter == null) return;
voter.Status = VotingStatus.Rejected;
voter.VotedAt = voterRejected.RejectedAt;
voting.TotalRejectedCount++;
}
private void HandleVotingStarted(VotingStarted votingStarted, VotingEntity voting)
{
voting.StartedAt = votingStarted.StartedAt;
}
private void HandleVotingClosed(VotingClosed votingClosed, VotingEntity voting)
{
voting.ClosedAt = votingClosed.ClosedAt;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment