C#重构方法以尊重干燥原理

C#重构方法以尊重干燥原理,c#,.net,refactoring,dry,C#,.net,Refactoring,Dry,我有一个问题,关于如何实现一个方法,以便能够在其他方法中使用它,而无需重复代码和遵守DRY原则。让我更好地解释一下,我有更多这样的方法: public async Task<int> AddCustomerPackageAsync(Guid customerId, CustomerPackageDto customerPackageDto) { var customer = await GetCustomerFromRepositoryAsync(customerId);

我有一个问题,关于如何实现一个方法,以便能够在其他方法中使用它,而无需重复代码和遵守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);
}
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);
}

如何重构泛型方法以实现目标? 有可能吗?
谢谢

这个实现怎么样

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;
}
也许您需要显式地指定泛型


我想这就是@想要告诉你的。

这个实现怎么样

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;
}
也许您需要显式地指定泛型


我想这就是@试图告诉你的。

你可以添加一个
Func
参数,让调用者首先传递添加逻辑<代码>返回等待任务。FromResult(id)这是多余的,只需在第二时间返回ids,只需注意,沿着这条路径走得越多,创建的抽象越多,方法越专业,除最琐碎的情况外,在所有情况下需要破解的东西越多,维护噩梦就越大。别误会我的意思,干掉你自己,但是不要害怕易于理解和调试的声明性代码。你可以添加一个
Func
参数,让调用者首先传递添加逻辑<代码>返回等待任务。FromResult(id)这是多余的,只需在第二时间返回ids,只需注意,沿着这条路径走得越多,创建的抽象越多,方法越专业,除最琐碎的情况外,在所有情况下需要破解的东西越多,维护噩梦就越大。别误会我的意思,干死你自己,但不要害怕易于理解和调试的声明性代码是的,你需要指定泛型类型,但除此之外,它工作得非常好。谢谢,您需要指定泛型类型,但除此之外,它工作得非常好。谢谢
_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);