public static async Task <GuessIPLocationResponse> RunAsync(
            GuessIPLocationRequest request,
            GetCacheKey getCacheKey,
            GetCacheAsync getCache,
            SetCacheAsync setCache
            )
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }
            if (!request.IsValid)
            {
                throw new ArgumentException(nameof(request));
            }

            string content = await getCache?.Invoke(getCacheKey?.Invoke(request));

            if (string.IsNullOrEmpty(content))
            {
                content = await QueryIPGeolocationAsync(request.IP);

                await setCache?.Invoke(getCacheKey?.Invoke(request), content);
            }

            return(new GuessIPLocationResponse(GetLocation(content), false));
        }
 public static async Task <GuessIPLocationResponse> RunAsync(GuessIPLocationRequest request)
 {
     return(await RunAsync(
                request,
                GetLocalCacheKey,
                GetLocalCacheAsync,
                SetLocalCacheAsync
                ));
 }
 public static string GetLocalCacheKey(GuessIPLocationRequest request) => $"{request.IP}.json";