Delegate/Func 的泛型函数
Generic Function with Delegate/Func
您好,我正在尝试创建一个接收请求的缓存方法和一个函数,以防先前没有为请求缓存任何内容,它将执行作为参数传递的委托函数。
我一直在看 Delegates 和 Funcs 的视频,但材料总是非常基础,而且 delegate 的 return 类型是强类型。我需要一些通用的东西用于不同的 dto(对象被缓存)。
我有一些自定义属性装饰了我想要缓存的 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;
}
如果我没理解错的话,代码工作正常,但接口有问题。你可以让它工作,但不能使用不同类型的代表和 return 类型。
*请注意,对于你想要实现的目标,可能有不同的方法可能会更好,但现在超出了范围。
在开始解释之前,让我简要总结一些关键细节:
- 接口用于在 类 之间分担责任,这些 类 的实例可以从客户端的角度以相同的方式使用
- 委托只是方法的接口,而不是 类
要解决此问题,需要执行 2 个步骤:
- 为不同的 DTO 创建接口
- 创建一个代表return这个接口
所以,鉴于我对问题域的结论是正确的:
*请注意,我还没有测试过这个,希望这能让你朝着正确的方向前进
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;
}
}
您好,我正在尝试创建一个接收请求的缓存方法和一个函数,以防先前没有为请求缓存任何内容,它将执行作为参数传递的委托函数。 我一直在看 Delegates 和 Funcs 的视频,但材料总是非常基础,而且 delegate 的 return 类型是强类型。我需要一些通用的东西用于不同的 dto(对象被缓存)。
我有一些自定义属性装饰了我想要缓存的 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;
}
如果我没理解错的话,代码工作正常,但接口有问题。你可以让它工作,但不能使用不同类型的代表和 return 类型。
*请注意,对于你想要实现的目标,可能有不同的方法可能会更好,但现在超出了范围。
在开始解释之前,让我简要总结一些关键细节:
- 接口用于在 类 之间分担责任,这些 类 的实例可以从客户端的角度以相同的方式使用
- 委托只是方法的接口,而不是 类
要解决此问题,需要执行 2 个步骤:
- 为不同的 DTO 创建接口
- 创建一个代表return这个接口
所以,鉴于我对问题域的结论是正确的:
*请注意,我还没有测试过这个,希望这能让你朝着正确的方向前进
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;
}
}