C# 重构方法以尊重 DRY 原则
C# Refactor method to respect the DRY principle
我有一个问题,关于如何实现一个方法以便能够在不重复代码和遵守 DRY 原则的情况下在其他方法中使用它。让我解释一下,我有更多这样的方法:
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);
}
然后:
public async Task<int> AddCustomerOrderAsync
public async Task<int> AddCustomerAddressAsync
.....
我考虑编写一个通用方法以在上述方法中使用,如下所示:
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);
}
我想在何处注入不同的存储库方法,例如:
_repository.AddCustomerOrderAsync(clientOrder);
或
_repository.AddCustomerPackageAsync(customerPackage);
如何重构泛型方法来实现我的目标?
有可能做到吗?
谢谢
这个实现怎么样?:
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;
}
并像这样调用它:
var orderId = await Add(customerId, dto, this._repository.AddCustomerOrderAsync);
var packageId = await Add(customerId, dto, this._repository.AddCustomerPackageAsync);
也许您需要明确指定泛型。
我想这就是@Biesi Grr 想告诉你的。
我有一个问题,关于如何实现一个方法以便能够在不重复代码和遵守 DRY 原则的情况下在其他方法中使用它。让我解释一下,我有更多这样的方法:
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);
}
然后:
public async Task<int> AddCustomerOrderAsync
public async Task<int> AddCustomerAddressAsync
.....
我考虑编写一个通用方法以在上述方法中使用,如下所示:
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);
}
我想在何处注入不同的存储库方法,例如:
_repository.AddCustomerOrderAsync(clientOrder);
或
_repository.AddCustomerPackageAsync(customerPackage);
如何重构泛型方法来实现我的目标? 有可能做到吗? 谢谢
这个实现怎么样?:
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;
}
并像这样调用它:
var orderId = await Add(customerId, dto, this._repository.AddCustomerOrderAsync);
var packageId = await Add(customerId, dto, this._repository.AddCustomerPackageAsync);
也许您需要明确指定泛型。
我想这就是@Biesi Grr 想告诉你的。