private async Task <List <AggregatedEvent> > GetAllArtistAggregatedEvents(AggregateTimeRange timeRange)
        {
            List <AggregatedEvent> result;
            string localStorageKey = LOCALSTORAGEKEY_ALLARTISTSAGGREGATEDEVENTS + timeRange;
            TimeCachedObject <List <AggregatedEvent> > cachedObject = await _localStorageService.GetItemAsync <TimeCachedObject <List <AggregatedEvent> > >(localStorageKey);

            if (cachedObject == null || cachedObject.NextUpdateHour < DateTimeOffset.UtcNow)
            {
                ArtistAggregatedEventsRequest request = new ArtistAggregatedEventsRequest()
                {
                    ArtistIds = new List <int>(), TimeSeries = timeRange
                };
                HttpResponseMessage responseMessage = await _httpClient.PostAsJsonAsync(_endpointAddress + "ArtistAggregatedEvents", request);

                string responseBody = await responseMessage.Content.ReadAsStringAsync();

                result = JsonConvert.DeserializeObject <List <AggregatedEvent> >(responseBody);
                DateTimeOffset nextUpdate = TimeCachedObject <object> .CalculateNextUpdateHour();

                cachedObject = new TimeCachedObject <List <AggregatedEvent> >()
                {
                    CachedObject   = result,
                    NextUpdateHour = nextUpdate
                };
                await _localStorageService.SetItemAsync(localStorageKey, cachedObject);
            }
            else
            {
                result = cachedObject.CachedObject;
            }
            return(result);
        }
        public async Task <List <ItemCount> > GetArtistPlayedOverTime(AggregateTimeRange timeRange, int artistId)
        {
            string           localStorageKey = LOCALSTORAGEKEY_ARTISTPLAYEDOVERTIME + artistId + "-" + timeRange;
            List <ItemCount> result;
            TimeCachedObject <List <ItemCount> > cachedObject = await _localStorageService.GetItemAsync <TimeCachedObject <List <ItemCount> > >(localStorageKey);

            if (cachedObject == null || cachedObject.NextUpdateHour < DateTimeOffset.UtcNow)
            {
                ArtistAggregatedEventsRequest request = new ArtistAggregatedEventsRequest()
                {
                    ArtistIds = new List <int>()
                    {
                        artistId
                    }, TimeSeries = timeRange
                };
                HttpResponseMessage responseMessage = await _httpClient.PostAsJsonAsync(_endpointAddress + "ArtistAggregatedEvents", request);

                string responseBody = await responseMessage.Content.ReadAsStringAsync();

                AggregatedEvent  temp  = JsonConvert.DeserializeObject <List <AggregatedEvent> >(responseBody)?.FirstOrDefault();
                List <ItemCount> items = temp.AggregatedEventSumSource.Select((x, i) => new ItemCount()
                {
                    Count = x.Value, ItemId = artistId, Name = x.Timestamp.ToString()
                }).ToList();
                Dictionary <string, (ItemCount itemCount, DateTimeOffset sortOrder)> buckets = GetItemCountBuckets(timeRange, artistId);
                foreach (var item in items)
                {
                    if (buckets.ContainsKey(item.Name))
                    {
                        buckets[item.Name].itemCount.Count = item.Count;
                    }
                }
                result = buckets.Values.OrderBy(x => x.sortOrder).Select(x => x.itemCount).ToList();
                DateTimeOffset nextUpdate = TimeCachedObject <object> .CalculateNextUpdateHour();

                cachedObject = new TimeCachedObject <List <ItemCount> >()
                {
                    CachedObject   = result,
                    NextUpdateHour = nextUpdate
                };
                await _localStorageService.SetItemAsync(localStorageKey, cachedObject);
            }
            else
            {
                result = cachedObject.CachedObject;
            }
            return(result);
        }