I am planning to implement Scrutor
public interface ICustomersRepository
{
Task<CustomerDto> GetCustomerAsync(Guid customerId);
Task<bool> SaveCustomer(CustomerDto customer);
}
public class CustomersRepository : ICustomersRepository
{
private readonly List<CustomerDto> _customers = new List<CustomerDto>
{
new CustomerDto{Id = Guid.Parse("64fa643f-2d35-46e7-b3f8-31fa673d719b"), Name = "Nick Chapsas"},
new CustomerDto{Id = Guid.Parse("fc7cdfc4-f407-4955-acbe-98c666ee51a2"), Name = "John Doe"},
new CustomerDto{Id = Guid.Parse("a46ac8f4-2ecd-43bf-a9e6-e557b9af1d6e"), Name = "Sam McRandom"}
};
public Task<CustomerDto> GetCustomerAsync(Guid customerId)
{
return Task.FromResult(_customers.SingleOrDefault(x => x.Id == customerId));
}
public Task<bool> SaveCustomer(CustomerDto customer)
{
return "Save Customer here and return bool";
}
}
Implementing cached repository:
public class CachedCustomersRepository : ICustomersRepository
{
private readonly ICustomersRepository _customersRepository; //CustomersRepository
private readonly ConcurrentDictionary<Guid, CustomerDto> _cache = new ConcurrentDictionary<Guid, CustomerDto>();
public CachedCustomersRepository(ICustomersRepository customersRepository)
{
_customersRepository = customersRepository;
}
public async Task<CustomerDto> GetCustomerAsync(Guid customerId)
{
if (_cache.ContainsKey(customerId))
{
return _cache[customerId];
}
var customer = await _customersRepository.GetCustomerAsync(customerId);
_cache.TryAdd(customerId, customer);
return customer;
}
}
And here is how i do DI:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddSingleton<ICustomersRepository, CustomersRepository>();
services.Decorate<ICustomersRepository, CachedCustomersRepository>();
}
The issue i see is ICustomerRepository have both GetCustomerAsync & SaveCustomer methods, I could implement ICustomerRepository in CacheCustomerRepository and define GetCustomerAsync method but how could I ignore SaveCustomer as that cannot go as cache method in CacheCustomerRepository class. If I don't define that method in CacheCustomerRepository i will be getting errors as missing implementation for interface, how to implement scrutor in clean way and is there a way implement only few methods that are required to be cached and rest can be in the main repository class ?
I can think of only including skeleton in the CacheCustomersRepository for save method but is it a clean way to do it, and also if my CustomerRepository have 50 methods of which only 5 methods needs cached implementation then it's very redundant and not a good way to put all the skeleton methods in the cache repository.
How can we implement Scrutor in a clean way ? Any suggestions ?