T Execute <T, T2>(RestRequestWithCache request, Func <IRestResponse <T2>, T> selector) where T : class, new() where T2 : class, new() { var cacheStyle = request.CacheSyle; var restClient = CreateClient(); switch (cacheStyle) { case RestRequestWithCache.CacheStyle.None: break; case RestRequestWithCache.CacheStyle.Immutable: var item = cache.Get(CacheKey(restClient, request)); if (item != null) { return((T)item); } break; case RestRequestWithCache.CacheStyle.IfNotModified: var obj = cache.Get(CacheKey(restClient, request)); if (obj != null) { var tuple = (Tuple <string, T>)obj; request.AddHeader("If-None-Match", tuple.Item1); } break; } LogRequest(request); var response = restClient.Execute <T2>(request); var data = default(T); switch (cacheStyle) { case RestRequestWithCache.CacheStyle.Immutable: if (response.StatusCode == HttpStatusCode.OK) { data = ProcessResponse(selector, response); cache.Set(CacheKey(restClient, request), data, new CacheItemPolicy()); } break; case RestRequestWithCache.CacheStyle.IfNotModified: switch (response.StatusCode) { case HttpStatusCode.OK: data = ProcessResponse(selector, response); var etag = response.Headers.FirstOrDefault(h => h.Name == "ETag"); if (etag != null) { cache.Set(CacheKey(restClient, request), Tuple.Create(etag.Value.ToString(), data), new CacheItemPolicy()); } break; case HttpStatusCode.NotModified: LogResponse(response); var obj = cache.Get(CacheKey(restClient, request)); if (obj != null) { var tuple = (Tuple <string, T>)obj; data = tuple.Item2; } break; } break; default: data = ProcessResponse(selector, response); break; } return(data); }