Skip to content

Merge develop to master #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jul 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion HttpClient.Caching.sln
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
README.md = README.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleAppSample", "Samples\ConsoleAppSample\ConsoleAppSample.csproj", "{592B2324-79AA-4973-8CE5-F65BD503641F}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleAppSample", "Samples\ConsoleAppSample\ConsoleAppSample.csproj", "{592B2324-79AA-4973-8CE5-F65BD503641F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{2AB15A56-D5AC-4CBB-95BF-241051541E52}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfSample", "Samples\WpfSample\WpfSample.csproj", "{750EA219-7FAB-44F6-B909-BC678CFF4BE4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -37,13 +39,18 @@ Global
{592B2324-79AA-4973-8CE5-F65BD503641F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{592B2324-79AA-4973-8CE5-F65BD503641F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{592B2324-79AA-4973-8CE5-F65BD503641F}.Release|Any CPU.Build.0 = Release|Any CPU
{750EA219-7FAB-44F6-B909-BC678CFF4BE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{750EA219-7FAB-44F6-B909-BC678CFF4BE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{750EA219-7FAB-44F6-B909-BC678CFF4BE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{750EA219-7FAB-44F6-B909-BC678CFF4BE4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{D8F20DC2-E69A-4432-A68B-FD4A8232BA43} = {82C933E0-5F3A-46DD-BE18-233590F11503}
{592B2324-79AA-4973-8CE5-F65BD503641F} = {2AB15A56-D5AC-4CBB-95BF-241051541E52}
{750EA219-7FAB-44F6-B909-BC678CFF4BE4} = {2AB15A56-D5AC-4CBB-95BF-241051541E52}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {46294172-BC59-4710-8105-CF322C619EA8}
Expand Down
71 changes: 33 additions & 38 deletions HttpClient.Caching/InMemory/CacheEntry.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
// Decompiled with JetBrains decompiler
// Type: Microsoft.Extensions.Caching.Memory.CacheEntry
// Assembly: Microsoft.Extensions.Caching.Memory, Version=2.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60
// MVID: 78529ED0-C4AD-4926-BA4D-60032404EE9B
using System;
using System.Collections;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Abstractions;
Expand All @@ -16,10 +12,10 @@ internal class CacheEntry : ICacheEntry
private static readonly Action<object> ExpirationCallback = ExpirationTokensExpired;
internal readonly object Lock = new object();
private bool added;
private readonly Action<CacheEntry> _notifyCacheOfExpiration;
private readonly Action<CacheEntry> _notifyCacheEntryDisposed;
private readonly Action<CacheEntry> notifyCacheOfExpiration;
private readonly Action<CacheEntry> notifyCacheEntryDisposed;
private IList<IDisposable> expirationTokenRegistrations;
private IList<PostEvictionCallbackRegistration> _postEvictionCallbacks;
private IList<PostEvictionCallbackRegistration> postEvictionCallbacks;
private bool isExpired;
internal IList<IChangeToken> expirationTokens;
internal DateTimeOffset? absoluteExpiration;
Expand All @@ -39,9 +35,8 @@ public TimeSpan? AbsoluteExpirationRelativeToNow
get { return this.absoluteExpirationRelativeToNow; }
set
{
TimeSpan? nullable = value;
TimeSpan zero = TimeSpan.Zero;
if ((nullable.HasValue ? (nullable.GetValueOrDefault() <= zero ? 1 : 0) : 0) != 0)
var nullable = value;
if ((nullable.HasValue ? (nullable.GetValueOrDefault() <= TimeSpan.Zero ? 1 : 0) : 0) != 0)
{
throw new ArgumentOutOfRangeException(nameof(this.AbsoluteExpirationRelativeToNow), value, "The relative expiration value must be positive.");
}
Expand All @@ -55,9 +50,8 @@ public TimeSpan? SlidingExpiration
get { return this.slidingExpiration; }
set
{
TimeSpan? nullable = value;
TimeSpan zero = TimeSpan.Zero;
if ((nullable.HasValue ? (nullable.GetValueOrDefault() <= zero ? 1 : 0) : 0) != 0)
var nullable = value;
if ((nullable.HasValue ? (nullable.GetValueOrDefault() <= TimeSpan.Zero ? 1 : 0) : 0) != 0)
{
throw new ArgumentOutOfRangeException(nameof(this.SlidingExpiration), value, "The sliding expiration value must be positive.");
}
Expand All @@ -83,12 +77,12 @@ public IList<PostEvictionCallbackRegistration> PostEvictionCallbacks
{
get
{
if (this._postEvictionCallbacks == null)
if (this.postEvictionCallbacks == null)
{
this._postEvictionCallbacks = new List<PostEvictionCallbackRegistration>();
this.postEvictionCallbacks = new List<PostEvictionCallbackRegistration>();
}

return this._postEvictionCallbacks;
return this.postEvictionCallbacks;
}
}

Expand All @@ -109,17 +103,17 @@ internal CacheEntry(object key, Action<CacheEntry> notifyCacheEntryDisposed, Act

if (notifyCacheEntryDisposed == null)
{
throw new ArgumentNullException("notifyCacheEntryDisposed");
throw new ArgumentNullException(nameof(notifyCacheEntryDisposed));
}

if (notifyCacheOfExpiration == null)
{
throw new ArgumentNullException("notifyCacheOfExpiration");
throw new ArgumentNullException(nameof(notifyCacheOfExpiration));
}

this.Key = key;
this._notifyCacheEntryDisposed = notifyCacheEntryDisposed;
this._notifyCacheOfExpiration = notifyCacheOfExpiration;
this.notifyCacheEntryDisposed = notifyCacheEntryDisposed;
this.notifyCacheOfExpiration = notifyCacheOfExpiration;
}

public void Dispose()
Expand All @@ -130,7 +124,7 @@ public void Dispose()
}

this.added = true;
this._notifyCacheEntryDisposed(this);
this.notifyCacheEntryDisposed(this);
//this.PropagateOptions(_added);
}

Expand Down Expand Up @@ -225,7 +219,7 @@ private static void ExpirationTokensExpired(object obj)
{
var cacheEntry = (CacheEntry)state;
cacheEntry.SetExpired(EvictionReason.TokenExpired);
cacheEntry._notifyCacheOfExpiration(cacheEntry);
cacheEntry.notifyCacheOfExpiration(cacheEntry);
}, obj, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
}

Expand All @@ -249,7 +243,7 @@ private void DetachTokens()

internal void InvokeEvictionCallbacks()
{
if (this._postEvictionCallbacks == null)
if (this.postEvictionCallbacks == null)
{
return;
}
Expand All @@ -262,7 +256,7 @@ internal void InvokeEvictionCallbacks()

private static void InvokeCallbacks(CacheEntry entry)
{
var callbackRegistrationList = Interlocked.Exchange(ref entry._postEvictionCallbacks, null);
var callbackRegistrationList = Interlocked.Exchange(ref entry.postEvictionCallbacks, null);
if (callbackRegistrationList == null)
{
return;
Expand All @@ -272,18 +266,19 @@ private static void InvokeCallbacks(CacheEntry entry)
{
try
{
PostEvictionDelegate evictionCallback = callbackRegistration.EvictionCallback;
var evictionCallback = callbackRegistration.EvictionCallback;
if (evictionCallback != null)
{
object key = entry.Key;
object obj = entry.Value;
EvictionReason evictionReason = entry.EvictionReason;
object state = callbackRegistration.State;
var key = entry.Key;
var obj = entry.Value;
var evictionReason = entry.EvictionReason;
var state = callbackRegistration.State;
evictionCallback.Invoke(key, obj, evictionReason, state);
}
}
catch (Exception ex)
{
Debug.WriteLine($"{ex}");
}
}
}
Expand All @@ -301,12 +296,12 @@ internal void PropagateOptions(CacheEntry parent)
{
lock (parent.Lock)
{
using (IEnumerator<IChangeToken> resource_0 = ((IEnumerable<IChangeToken>)this.expirationTokens).GetEnumerator())
using (var changeTokenEnumerator = this.expirationTokens.GetEnumerator())
{
while (((IEnumerator)resource_0).MoveNext())
while (changeTokenEnumerator.MoveNext())
{
IChangeToken local_5 = resource_0.Current;
CacheEntryExtensions.AddExpirationToken((ICacheEntry)parent, local_5);
var changeToken = changeTokenEnumerator.Current;
parent.AddExpirationToken(changeToken);
}
}
}
Expand All @@ -320,9 +315,9 @@ internal void PropagateOptions(CacheEntry parent)

if (parent.absoluteExpiration.HasValue)
{
DateTimeOffset? absoluteExpiration1 = this.absoluteExpiration;
DateTimeOffset? absoluteExpiration2 = parent.absoluteExpiration;
if ((absoluteExpiration1.HasValue & absoluteExpiration2.HasValue ? (absoluteExpiration1.GetValueOrDefault() < absoluteExpiration2.GetValueOrDefault() ? 1 : 0) : 0) == 0)
var absoluteExpiration = this.absoluteExpiration;
var parentAbsoluteExpiration = parent.absoluteExpiration;
if ((absoluteExpiration.HasValue & parentAbsoluteExpiration.HasValue ? (absoluteExpiration.GetValueOrDefault() < parentAbsoluteExpiration.GetValueOrDefault() ? 1 : 0) : 0) == 0)
{
return;
}
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ Use the following command to install HttpClient.Caching using NuGet package mana

You can use this library in any .Net project which is compatible to .Net Framework 4.5+ and .Net Standard 1.2+ (e.g. Xamarin Android, iOS, Universal Windows Platform, etc.)

### The Purpose of HTTP Caching
HTTP Caching affects both involved communication peers, the client and the server. On the server-side, caching is appropriate for improving throughput (scalability). HTTP caching doesn't make a single HTTP call faster but it can lead to better response performance in high-load scenarios. On the client-side, caching is used to avoid unnecessarily repetitiv HTTP calls. This leads to less waiting time on the client-side since cache reads have naturally a much better response performance than HTTP calls over relatively slow network links.

### API Usage
#### Using MemoryCache
Declare IMemoryCache in your API service, either by creating an instance manually or by injecting IMemoryCache into your API service class.
Expand Down Expand Up @@ -94,5 +97,8 @@ static void Main(string[] args)
}
```

### Further Reading
[How-to: HTTP Caching for RESTful & Hypermedia APIs](https://www.apiacademy.co/articles/2015/12/how-to-http-caching-for-restful-hypermedia-apis)

### License
This project is Copyright &copy; 2018 [Thomas Galliker](https://ch.linkedin.com/in/thomasgalliker). Free for non-commercial use. For commercial use please contact the author.
6 changes: 6 additions & 0 deletions Samples/WpfSample/App.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7" />
</startup>
</configuration>
10 changes: 10 additions & 0 deletions Samples/WpfSample/App.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Application x:Class="WpfSample.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Views/WeatherView.xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
d1p1:Ignorable="d"
xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006">
<Application.Resources>
<ResourceDictionary />
</Application.Resources>
</Application>
11 changes: 11 additions & 0 deletions Samples/WpfSample/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Windows;

namespace WpfSample
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}
12 changes: 12 additions & 0 deletions Samples/WpfSample/Extensions/TimeSpanExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;

namespace WpfSample.Extensions
{
public static class TimeSpanExtensions
{
public static string ToSecondsString(this TimeSpan timeSpan)
{
return $"{timeSpan.TotalSeconds:0.0000}s";
}
}
}
25 changes: 25 additions & 0 deletions Samples/WpfSample/Model/City.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Newtonsoft.Json;

namespace WpfSample.Model
{
public class City
{
[JsonProperty("id")]
public int Id { get; set; }

[JsonProperty("name")]
public string Name { get; set; }

[JsonProperty("coord")]
public Coord Coord { get; set; }

[JsonProperty("country")]
public string Country { get; set; }

[JsonProperty("population")]
public int Population { get; set; }

[JsonProperty("sys")]
public Sys Sys { get; set; }
}
}
10 changes: 10 additions & 0 deletions Samples/WpfSample/Model/Clouds.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Newtonsoft.Json;

namespace WpfSample.Model
{
public class Clouds
{
[JsonProperty("all")]
public int CloudinessPercent { get; set; } = 0;
}
}
13 changes: 13 additions & 0 deletions Samples/WpfSample/Model/Coord.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Newtonsoft.Json;

namespace WpfSample.Model
{
public class Coord
{
[JsonProperty("lon")]
public double Longitude { get; set; } = 0;

[JsonProperty("lat")]
public double Latitude { get; set; } = 0;
}
}
22 changes: 22 additions & 0 deletions Samples/WpfSample/Model/Main.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Newtonsoft.Json;

namespace WpfSample.Model
{
public class Main
{
[JsonProperty("temp")]
public double Temperature { get; set; } = 0;

[JsonProperty("pressure")]
public double Pressure { get; set; } = 0;

[JsonProperty("humidity")]
public double Humidity { get; set; } = 0;

[JsonProperty("temp_min")]
public double MinTemperature { get; set; } = 0;

[JsonProperty("temp_max")]
public double MaxTemperature { get; set; } = 0;
}
}
10 changes: 10 additions & 0 deletions Samples/WpfSample/Model/Sys.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Newtonsoft.Json;

namespace WpfSample.Model
{
public class Sys
{
[JsonProperty("country")]
public string Country { get; set; } = string.Empty;
}
}
8 changes: 8 additions & 0 deletions Samples/WpfSample/Model/Units.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace WpfSample.Model
{
public enum Units
{
Imperial,
Metric
}
}
19 changes: 19 additions & 0 deletions Samples/WpfSample/Model/Weather.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Newtonsoft.Json;

namespace WpfSample.Model
{
public class Weather
{
[JsonProperty("id")]
public int Id { get; set; } = 0;

[JsonProperty("main")]
public string Main { get; set; } = string.Empty;

[JsonProperty("description")]
public string Description { get; set; } = string.Empty;

[JsonProperty("icon")]
public string Icon { get; set; } = string.Empty;
}
}
Loading