【问题标题】:Generic Function with Delegate/Func带有 Delegate/Func 的通用函数
【发布时间】:2020-11-06 10:45:35
【问题描述】:

您好,我正在尝试创建一个接收请求的缓存方法和一个函数,以防以前没有为请求缓存任何内容,它将执行作为参数传递的委托函数。 我一直在看 Delegates 和 Funcs 的视频,但材料总是非常基础,并且 delegate 的返回类型是强类型。我需要一些通用的东西来用于不同的 dtos(对象被缓存)。

我有一些自定义属性来装饰我想要缓存的 ClasseDTO,但这工作正常,所以请忽略。

public async Task<AdministrationDashboardDto> GetAdministrationKPIsAsync()
{
    AdministrationDashboardDto dto = new AdministrationDashboardDto();

    var x = await TryGetInCacheAsync(dto, () => _iKpisService.GetAdministrationKPIsAsync());

    return (AdministrationDashboardDto)x;
}

private async Task<object> TryGetInCacheAsync<T>(object request, Func<T> p)
{
   var cacheQuery = request.GetType().GetCustomAttribute<CacheObjectAttribute>();
    if (cacheQuery != null)
    {
        var cacheKey = string.IsNullOrEmpty(cacheQuery.CacheKey)
            ? CacheHelper.GenerateCacheKeyFromRequest(dto)
            : cacheQuery.CacheKey;

        var cachedResponse = await _cacheService.GetCacheValueAsync(cacheKey);
        if (cachedResponse != null)
        {
            //_logger.LogInformation($"Request {typeof(TRequest).Name} served from cache");
            return cachedResponse;
        }

        var actualResponse = await Task.FromResult(p);
        await _cacheService.SetCacheValueAsync(cacheKey, actualResponse, cacheQuery.TimeSpanForCacheInvalidation);
        return actualResponse;
    }

    return null;
}

【问题讨论】:

  • 你是在var actualResponse = p()之后吗?您正在创建一个Task&lt;Func&lt;T&gt;&gt;,其中Task 已经完成,这似乎毫无意义。
  • 您的目标是在缓存中存储一​​个函数?为什么?有什么意义?
  • @CaiusJard nops,如果该请求的缓存中没有任何内容,则将执行委托函数。然后该函数将执行从源获取数据并将其添加到缓存中以供下次使用。

标签: c# asynchronous delegates


【解决方案1】:

如果我理解正确,代码工作正常,但接口是问题所在。你可以让它工作,但不能使用不同类型的委托和返回类型。

*请注意,也许对你想要实现的目标采用不同的方法可能会更好,但超出了范围现在。

在我开始解释之前,让我简要总结一些关键细节:

  • 接口用于在类之间分担责任,从客户端的角度来看,这些类的实例可以以相同的方式使用
  • 委托只是方法的接口而不是类

要解决此问题,需要采取 2 个步骤:

  • 为不同的 DTO 创建接口
  • 创建一个返回此接口的委托



所以,鉴于我对问题域的结论是正确的:

*请注意,我尚未对此进行测试,希望这能让您朝着正确的方向前进

    public interface DTO { }

    public class AdministrationDashboardDto : DTO {  }

    public delegate Task<DTO> GetDTO();

    public class TestClass
    {
        public async Task<DTO> GetAdministrationKPIsAsync()
        {
            AdministrationDashboardDto dto = new AdministrationDashboardDto();

            var x = await TryGetInCacheAsync(dto, () => _iKpisService.GetAdministrationKPIsAsync());

            return (AdministrationDashboardDto)x;

        }

        //PAY ATTENTION TO DELEGATE
        private async Task<DTO> TryGetInCacheAsync<T>(object request, GetDTO p)
        {
            var cacheQuery = request.GetType().GetCustomAttribute<CacheObjectAttribute>();
            if (cacheQuery != null)
            {
                var cacheKey = string.IsNullOrEmpty(cacheQuery.CacheKey)
                    ? CacheHelper.GenerateCacheKeyFromRequest(dto)
                    : cacheQuery.CacheKey;

                var cachedResponse = await _cacheService.GetCacheValueAsync(cacheKey);
                if (cachedResponse != null)
                {
                    //_logger.LogInformation($"Request {typeof(TRequest).Name} served from cache");
                    return cachedResponse;
                }

                //change to INVOKE METHOD ON DELEGATE
                var actualResponse = await p.Invoke();
                await _cacheService.SetCacheValueAsync(cacheKey, actualResponse, cacheQuery.TimeSpanForCacheInvalidation);
                return actualResponse;
            }

            return null;

        }
    }

【讨论】:

  • 好主意。工作得很好。
  • 谢谢,很高兴能帮上忙
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多