Skip to content

Instantly share code, notes, and snippets.

@ebicoglu
Created May 29, 2020 06:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ebicoglu/d7d4a05a20a5393b64f1ffcd17a5f52c to your computer and use it in GitHub Desktop.
Save ebicoglu/d7d4a05a20a5393b64f1ffcd17a5f52c to your computer and use it in GitHub Desktop.
Creating Sequential Numbers
public class EfCoreSequentialNumberRepository : EfCoreRepository<IQaDbContext, SequentialNumber, Guid>, ISequentialNumberRepository
{
public EfCoreSequentialNumberRepository(IDbContextProvider<IQaDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
public virtual SequentialNumber FindBySequenceName(string sequenceName)
{
return DbSet.FirstOrDefault(n => n.SequenceName == sequenceName);
}
}
public interface ISequentialNumberManager : IDomainService
{
Task<int> GetNextAsync(string sequenceName);
}
public interface ISequentialNumberRepository : IBasicRepository<SequentialNumber, Guid>
{
[CanBeNull]
SequentialNumber FindBySequenceName([NotNull] string sequenceName);
}
public class SequentialNumber : AggregateRoot<Guid>, IMultiTenant
{
public virtual Guid? TenantId { get; protected set; }
public virtual string SequenceName { get; protected set; }
public virtual int CurrentValue { get; protected set; }
protected SequentialNumber()
{
}
public SequentialNumber([NotNull]string sequenceName, Guid? tenantId = null)
{
SequenceName = Check.NotNull(sequenceName, nameof(sequenceName));
TenantId = tenantId;
CurrentValue = 1;
ConcurrencyStamp = Guid.NewGuid().ToString();
}
public void Increment()
{
++CurrentValue;
}
}
public class SequentialNumberManager : DomainService, ISequentialNumberManager
{
private const int GetNextTryCount = 3;
private readonly ISequentialNumberRepository _sequentialNumberRepository;
public SequentialNumberManager(ISequentialNumberRepository sequentialNumberRepository)
{
_sequentialNumberRepository = sequentialNumberRepository;
}
public async Task<int> GetNextAsync([NotNull] string sequenceName)
{
Check.NotNull(sequenceName, nameof(sequenceName));
Exception exception = null;
for (var i = 0; i < GetNextTryCount; i++)
{
try
{
return await GetNextInternalAsync(sequenceName);
}
catch (Exception e)
{
exception = e;
}
}
throw exception;
}
private async Task<int> GetNextInternalAsync(string sequenceName)
{
var sequentialNumber = _sequentialNumberRepository.FindBySequenceName(sequenceName);
if (sequentialNumber == null)
{
sequentialNumber = await _sequentialNumberRepository.InsertAsync(new SequentialNumber(sequenceName, CurrentTenant.Id), autoSave: true);
}
else
{
sequentialNumber.Increment();
await _sequentialNumberRepository.UpdateAsync(sequentialNumber, autoSave: true);
}
return sequentialNumber.CurrentValue;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment