initial commit

This commit is contained in:
2024-07-14 19:45:34 +07:00
commit d568ec6970
21 changed files with 594 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
using Domain.Models;
using Microsoft.EntityFrameworkCore;
namespace DAL.Database;
public class DatabaseContext: DbContext
{
public DbSet<Product> Products { get; set; }
public DbSet<Description> Descriptions { get; set; }
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options)
{
Database.EnsureCreated();
}
}

10
DAL/IRepository.cs Normal file
View File

@@ -0,0 +1,10 @@
namespace DAL;
public interface IRepository<T>
{
Task<T> Get(int id, int cacheLifetime, CancellationToken token);
Task<List<T>> GetAll(int cacheLifeTime, CancellationToken token);
Task Delete(int id, CancellationToken token);
Task Update(T entity, int cacheLifetime, CancellationToken token);
Task Create(T entity, int cacheLifeTime, CancellationToken token);
}

View File

@@ -0,0 +1,8 @@
using Domain.Models;
namespace DAL.Repositories;
public interface IProductRepository: IRepository<Product>
{
}

View File

@@ -0,0 +1,149 @@
using System.Text.Json;
using DAL.Database;
using Domain.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging;
namespace DAL.Repositories;
public class ProductRepository: IProductRepository
{
private readonly DatabaseContext _db;
private readonly ILogger _logger;
private readonly IDistributedCache _cache;
public ProductRepository(DatabaseContext db, ILogger logger, IDistributedCache cache)
{
_db = db;
_logger = logger;
_cache = cache;
}
public async Task<Product> Get(int id, int cacheLifetime, CancellationToken token)
{
var productCache = await _cache.GetAsync(id.ToString(), token);
var product = new Product();
if(productCache is not null)
product = JsonSerializer.Deserialize<Product>(productCache);
if (product is not null)
return product;
product = await _db.Products.FindAsync(id) ??
throw new KeyNotFoundException("Product not found");
_db.Entry(product).Reference(p => p.Description).Load();
await _cache.SetStringAsync(
product.Id.ToString(),
JsonSerializer.Serialize(product),
new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(cacheLifetime)
}, token);
return product;
}
public async Task<List<Product>> GetAll(int cacheLifeTime, CancellationToken token)
{
var productsCache = await _cache.GetAsync("Products", token);
var products = new List<Product>();
if (productsCache is not null)
products = JsonSerializer.Deserialize<List<Product>> (productsCache);
if(products is not null && products.Count() > 0)
return products;
products = await _db.Products
.Include(p => p.Description)
.ToListAsync(token)
?? throw new NullReferenceException("Database is empty");
await _cache.SetStringAsync("Products",
JsonSerializer.Serialize(products),
new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(cacheLifeTime)
}, token);
return products;
}
public async Task Delete(int id, CancellationToken token)
{
var product = await _db.Products.FindAsync(id) ??
throw new KeyNotFoundException("Product not found");
_db.Products.Remove(product);
await _cache.RemoveAsync(id.ToString(), token);
await _db.SaveChangesAsync();
}
public async Task Update(Product entity, int cacheLifetime, CancellationToken token)
{
var product = await _db.Products.FindAsync(entity.Id) ??
throw new KeyNotFoundException("Product not found");
_db.Entry(product).Reference(p => p.Description).Load();
_db.Entry(product).CurrentValues.SetValues(entity);
_db.Entry(product.Description).CurrentValues.SetValues(entity.Description);
await _cache.RemoveAsync(product.Id.ToString(), token);
await _cache.SetStringAsync(product.Id.ToString(),
JsonSerializer.Serialize(entity),
new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(cacheLifetime)
}, token);
await _db.SaveChangesAsync();
}
public async Task Create(Product entity, int cacheLifeTime, CancellationToken token)
{
using (var transaction = _db.Database.BeginTransaction())
{
try
{
await _db.Products.AddAsync(entity);
await _db.Descriptions.AddAsync(entity.Description);
await _db.SaveChangesAsync();
transaction.Commit();
var products = await _db.Products
.Include(p => p.Description)
.ToListAsync()
?? throw new NullReferenceException("Database is empty");
await _cache.RemoveAsync("Products", token);
await _cache.SetStringAsync("Products",
JsonSerializer.Serialize(products),
new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(cacheLifeTime)
}, token);
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
transaction.Rollback();
throw new Exception(ex.Message);
}
finally
{
transaction.Dispose();
}
}
}
}