Initial commit

This commit is contained in:
Mark J Price 2022-09-05 10:51:15 +01:00
parent ded4870ccb
commit c4cde7875a
2 changed files with 32 additions and 32 deletions

View file

@ -6,21 +6,21 @@ namespace Northwind.WebApi.Repositories;
public class CustomerRepository : ICustomerRepository public class CustomerRepository : ICustomerRepository
{ {
// use a static thread-safe dictionary field to cache the customers // Use a static thread-safe dictionary field to cache the customers.
private static ConcurrentDictionary private static ConcurrentDictionary
<string, Customer>? customersCache; <string, Customer>? customersCache;
// use an instance data context field because it should not be // Use an instance data context field because it should not be
// cached due to their internal caching // cached due to the data context having internal caching.
private NorthwindContext db; private NorthwindContext db;
public CustomerRepository(NorthwindContext injectedContext) public CustomerRepository(NorthwindContext injectedContext)
{ {
db = injectedContext; db = injectedContext;
// pre-load customers from database as a normal // Pre-load customers from database as a normal
// Dictionary with CustomerId as the key, // Dictionary with CustomerId as the key,
// then convert to a thread-safe ConcurrentDictionary // then convert to a thread-safe ConcurrentDictionary.
if (customersCache is null) if (customersCache is null)
{ {
customersCache = new ConcurrentDictionary<string, Customer>( customersCache = new ConcurrentDictionary<string, Customer>(
@ -30,16 +30,16 @@ public class CustomerRepository : ICustomerRepository
public async Task<Customer?> CreateAsync(Customer c) public async Task<Customer?> CreateAsync(Customer c)
{ {
// normalize CustomerId into uppercase // Normalize CustomerId into uppercase.
c.CustomerId = c.CustomerId.ToUpper(); c.CustomerId = c.CustomerId.ToUpper();
// add to database using EF Core // Add to database using EF Core.
EntityEntry<Customer> added = await db.Customers.AddAsync(c); EntityEntry<Customer> added = await db.Customers.AddAsync(c);
int affected = await db.SaveChangesAsync(); int affected = await db.SaveChangesAsync();
if (affected == 1) if (affected == 1)
{ {
if (customersCache is null) return c; if (customersCache is null) return c;
// if the customer is new, add it to cache, else // If the customer is new, add it to cache, else
// call UpdateCache method // call UpdateCache method.
return customersCache.AddOrUpdate(c.CustomerId, c, UpdateCache); return customersCache.AddOrUpdate(c.CustomerId, c, UpdateCache);
} }
else else
@ -50,14 +50,14 @@ public class CustomerRepository : ICustomerRepository
public Task<IEnumerable<Customer>> RetrieveAllAsync() public Task<IEnumerable<Customer>> RetrieveAllAsync()
{ {
// for performance, get from cache // For performance, get from cache.
return Task.FromResult(customersCache is null return Task.FromResult(customersCache is null
? Enumerable.Empty<Customer>() : customersCache.Values); ? Enumerable.Empty<Customer>() : customersCache.Values);
} }
public Task<Customer?> RetrieveAsync(string id) public Task<Customer?> RetrieveAsync(string id)
{ {
// for performance, get from cache // For performance, get from cache.
id = id.ToUpper(); id = id.ToUpper();
if (customersCache is null) return null!; if (customersCache is null) return null!;
customersCache.TryGetValue(id, out Customer? c); customersCache.TryGetValue(id, out Customer? c);
@ -82,15 +82,15 @@ public class CustomerRepository : ICustomerRepository
public async Task<Customer?> UpdateAsync(string id, Customer c) public async Task<Customer?> UpdateAsync(string id, Customer c)
{ {
// normalize customer Id // Normalize customer Id.
id = id.ToUpper(); id = id.ToUpper();
c.CustomerId = c.CustomerId.ToUpper(); c.CustomerId = c.CustomerId.ToUpper();
// update in database // Update in database.
db.Customers.Update(c); db.Customers.Update(c);
int affected = await db.SaveChangesAsync(); int affected = await db.SaveChangesAsync();
if (affected == 1) if (affected == 1)
{ {
// update in cache // Update in cache.
return UpdateCache(id, c); return UpdateCache(id, c);
} }
return null; return null;
@ -99,7 +99,7 @@ public class CustomerRepository : ICustomerRepository
public async Task<bool?> DeleteAsync(string id) public async Task<bool?> DeleteAsync(string id)
{ {
id = id.ToUpper(); id = id.ToUpper();
// remove from database // Remove from database.
Customer? c = db.Customers.Find(id); Customer? c = db.Customers.Find(id);
if (c is null) return null; if (c is null) return null;
db.Customers.Remove(c); db.Customers.Remove(c);
@ -107,7 +107,7 @@ public class CustomerRepository : ICustomerRepository
if (affected == 1) if (affected == 1)
{ {
if (customersCache is null) return null; if (customersCache is null) return null;
// remove from cache // Remove from cache.
return customersCache.TryRemove(id, out c); return customersCache.TryRemove(id, out c);
} }
else else

View file

@ -6,21 +6,21 @@ namespace Northwind.WebApi.Repositories;
public class CustomerRepository : ICustomerRepository public class CustomerRepository : ICustomerRepository
{ {
// use a static thread-safe dictionary field to cache the customers // Use a static thread-safe dictionary field to cache the customers.
private static ConcurrentDictionary private static ConcurrentDictionary
<string, Customer>? customersCache; <string, Customer>? customersCache;
// use an instance data context field because it should not be // Use an instance data context field because it should not be
// cached due to their internal caching // cached due to the data context having internal caching.
private NorthwindContext db; private NorthwindContext db;
public CustomerRepository(NorthwindContext injectedContext) public CustomerRepository(NorthwindContext injectedContext)
{ {
db = injectedContext; db = injectedContext;
// pre-load customers from database as a normal // Pre-load customers from database as a normal
// Dictionary with CustomerId as the key, // Dictionary with CustomerId as the key,
// then convert to a thread-safe ConcurrentDictionary // then convert to a thread-safe ConcurrentDictionary.
if (customersCache is null) if (customersCache is null)
{ {
customersCache = new ConcurrentDictionary<string, Customer>( customersCache = new ConcurrentDictionary<string, Customer>(
@ -30,16 +30,16 @@ public class CustomerRepository : ICustomerRepository
public async Task<Customer?> CreateAsync(Customer c) public async Task<Customer?> CreateAsync(Customer c)
{ {
// normalize CustomerId into uppercase // Normalize CustomerId into uppercase.
c.CustomerId = c.CustomerId.ToUpper(); c.CustomerId = c.CustomerId.ToUpper();
// add to database using EF Core // Add to database using EF Core.
EntityEntry<Customer> added = await db.Customers.AddAsync(c); EntityEntry<Customer> added = await db.Customers.AddAsync(c);
int affected = await db.SaveChangesAsync(); int affected = await db.SaveChangesAsync();
if (affected == 1) if (affected == 1)
{ {
if (customersCache is null) return c; if (customersCache is null) return c;
// if the customer is new, add it to cache, else // If the customer is new, add it to cache, else
// call UpdateCache method // call UpdateCache method.
return customersCache.AddOrUpdate(c.CustomerId, c, UpdateCache); return customersCache.AddOrUpdate(c.CustomerId, c, UpdateCache);
} }
else else
@ -50,14 +50,14 @@ public class CustomerRepository : ICustomerRepository
public Task<IEnumerable<Customer>> RetrieveAllAsync() public Task<IEnumerable<Customer>> RetrieveAllAsync()
{ {
// for performance, get from cache // For performance, get from cache.
return Task.FromResult(customersCache is null return Task.FromResult(customersCache is null
? Enumerable.Empty<Customer>() : customersCache.Values); ? Enumerable.Empty<Customer>() : customersCache.Values);
} }
public Task<Customer?> RetrieveAsync(string id) public Task<Customer?> RetrieveAsync(string id)
{ {
// for performance, get from cache // For performance, get from cache.
id = id.ToUpper(); id = id.ToUpper();
if (customersCache is null) return null!; if (customersCache is null) return null!;
customersCache.TryGetValue(id, out Customer? c); customersCache.TryGetValue(id, out Customer? c);
@ -82,15 +82,15 @@ public class CustomerRepository : ICustomerRepository
public async Task<Customer?> UpdateAsync(string id, Customer c) public async Task<Customer?> UpdateAsync(string id, Customer c)
{ {
// normalize customer Id // Normalize customer Id.
id = id.ToUpper(); id = id.ToUpper();
c.CustomerId = c.CustomerId.ToUpper(); c.CustomerId = c.CustomerId.ToUpper();
// update in database // Update in database.
db.Customers.Update(c); db.Customers.Update(c);
int affected = await db.SaveChangesAsync(); int affected = await db.SaveChangesAsync();
if (affected == 1) if (affected == 1)
{ {
// update in cache // Update in cache.
return UpdateCache(id, c); return UpdateCache(id, c);
} }
return null; return null;
@ -99,7 +99,7 @@ public class CustomerRepository : ICustomerRepository
public async Task<bool?> DeleteAsync(string id) public async Task<bool?> DeleteAsync(string id)
{ {
id = id.ToUpper(); id = id.ToUpper();
// remove from database // Remove from database.
Customer? c = db.Customers.Find(id); Customer? c = db.Customers.Find(id);
if (c is null) return null; if (c is null) return null;
db.Customers.Remove(c); db.Customers.Remove(c);
@ -107,7 +107,7 @@ public class CustomerRepository : ICustomerRepository
if (affected == 1) if (affected == 1)
{ {
if (customersCache is null) return null; if (customersCache is null) return null;
// remove from cache // Remove from cache.
return customersCache.TryRemove(id, out c); return customersCache.TryRemove(id, out c);
} }
else else