Reputation: 874
I have a question about how to implement a method to be able to use it in other methods without repeating code and respecting the DRY principle. Let me explain better, I have more methods like this:
public async Task<int> AddCustomerPackageAsync(Guid customerId, CustomerPackageDto customerPackageDto)
{
var customer = await GetCustomerFromRepositoryAsync(customerId);
var customerPackage = _mapper.Map<CustomerPackage>(customerPackageDto, options =>
options.AfterMap((o, dest) =>
{
dest.customerID = customer.Id;
dest.Added = DateTime.UtcNow;
}))
var id = await _repository.AddCustomerPackageAsync(customerPackage);
return await Task.FromResult(id);
}
then:
public async Task<int> AddCustomerOrderAsync
public async Task<int> AddCustomerAddressAsync
.....
I thought about writing a generic method to use in the methods above, like this:
private async Task<int> Add<T, TResult>(Guid customerId, T dto) where TResult : CustomerBase
{
var customer = await GetClientFromRepositoryAsync(customerId);
var entity = _mapper.Map<TResult>(dto, options =>
{
options.AfterMap((o, customerBase) => customerBase.Id = customer.Id);
});
// Inject here different _repository methods
// var id = async _repository.Add....
return await Task.FromResult(id);
}
Where i want inject different repository methods like:
_repository.AddCustomerOrderAsync(clientOrder);
or
_repository.AddCustomerPackageAsync(customerPackage);
How can I refactor the generic method to get my goal? It's possible to do it? Thank you
Upvotes: 0
Views: 75
Reputation: 3446
What about this implementation?:
private async Task<int> Add<T, TResult>(Guid customerId, T dto, Func<TResult, Task<int>> addToRepo) where TResult : CustomerBase
{
var customer = await GetClientFromRepositoryAsync(customerId);
var entity = _mapper.Map<TResult>(dto, options =>
{
options.AfterMap((o, customerBase) => customerBase.Id = customer.Id);
});
// You can write it in one line - it's just to be clear about returning the id.
var id = await addToRepo(entity);
return id;
}
And invoke it like:
var orderId = await Add(customerId, dto, this._repository.AddCustomerOrderAsync);
var packageId = await Add(customerId, dto, this._repository.AddCustomerPackageAsync);
Maybe you need to specify the generics explicitly.
I think that is what @Biesi Grr was trying to tell you.
Upvotes: 2