Cache content asynchronously inside NancyFx. Allows you to set a timespan of lifecycle for your cache. Also allows to redefine the desired Cache backend and desires key request. By default it provides a default memory cache and a default uri key.
Note: Since Nancyfx is no longer being maintained i will be deprioritizing this library, please check here for details
This library targets Nancyfx 2 and above.
Appveyor | Branch | Coverage |
---|---|---|
master | ||
develop |
Package | NuGet (Stable) | MyGet (Prerelease) |
---|---|---|
Nancy.RapidCache | ||
Nancy.RapidCache.Redis | ||
Nancy.RapidCache.Couchbase | ||
Nancy.RapidCache.IMemory |
Install via nuget https://nuget.org/packages/Nancy.RapidCache
PM> Install-Package Nancy.RapidCache
The following example is using the default "In-Memory" CacheStore which is nothing more than a concurrent dictionary.
- Add to your Nancy bootstrapper
using Nancy.RapidCache.Extensions;
using Nancy.Routing;
namespace WebApplication
{
public class ApplicationBootrapper : Nancy.DefaultNancyBootstrapper
{
protected override void ApplicationStartup(Nancy.TinyIoc.TinyIoCContainer container, Nancy.Bootstrapper.IPipelines pipelines)
{
base.ApplicationStartup(container, pipelines);
/* Enable rapidcache, vary by url, query, form and accept header */
this.EnableRapidCache(container.Resolve<IRouteResolver>(), ApplicationPipelines, new[] { "query", "form", "accept" });
}
}
}
- Enable caching by adding the "AsCacheable" extension method to any of your routes
using System;
using Nancy;
using Nancy.RapidCache.Extensions;
namespace WebApplication
{
public class ExampleModule : NancyModule
{
public ExampleModule()
{
Get("/", _ =>
{
/* cache view for 30 secs */
return View["hello.html"].AsCacheable(DateTime.Now.AddSeconds(30));
});
Get("/CachedResponse", _ =>
{
/* cache response for 30 secs */
return Response.AsText("hello").AsCacheable(DateTime.Now.AddSeconds(30));
});
}
}
}
Or alternatively, set the Cache on all requests by using an after request on the start of the pipeline.
using Nancy.RapidCache.Extensions;
using Nancy.Routing;
namespace WebApplication
{
public class ApplicationBootrapper : Nancy.DefaultNancyBootstrapper
{
protected override void ApplicationStartup(Nancy.TinyIoc.TinyIoCContainer container, Nancy.Bootstrapper.IPipelines pipelines)
{
base.ApplicationStartup(container, pipelines);
/* Enable RapidCache, vary by url params query, form and accept headers */
this.EnableRapidCache(container.Resolve<IRouteResolver>(), ApplicationPipelines, new[] { "query", "form", "accept" });
pipelines.AfterRequest.AddItemToStartOfPipeline(ConfigureCache);
}
public void ConfigureCache(NancyContext context)
{
/* Cache all responses by 30 seconds with status code OK */
context.Response = context.Response.AsCacheable(DateTime.Now.AddSeconds(30));
}
}
}
*Keep in mind that for Post methods, the requests body is NOT part of the key in this scenario. In context, you can filter by the values of:
- Query
- Form values
- Accept Headers
along with the url that identifies your resource (this is using the DefaultKeyGenerator).
When using Nancy in self hosting mode, you can use the DiskCacheStore to enable caching throught RapidCache to a tmp file.
using Nancy.RapidCache.CacheStore;
using Nancy.RapidCache.Extensions;
using Nancy.Routing;
namespace WebApplication
{
public class ApplicationBootrapper : Nancy.DefaultNancyBootstrapper
{
protected override void ApplicationStartup(Nancy.TinyIoc.TinyIoCContainer container, Nancy.Bootstrapper.IPipelines pipelines)
{
base.ApplicationStartup(container, pipelines);
/* Enable RapidCache using the DiskCacheStore, vary by url params id,query,takem, skip and accept header */
this.EnableRapidCache(container.Resolve<IRouteResolver>(), ApplicationPipelines, new[] { "query", "form", "accept" }, new DiskCacheStore("c:/tmp/cache"));
}
}
}
One of the lightweight alternatives to the MemoryCacheStore which is included as part of the RapidCache library is the external IMemoryCacheStore, which requires a separate nuget lib installation:
PM> Install-Package Nancy.RapidCache.IMemory
the difference being that the store uses the Microsoft.Extensions.Caching.Memory
as a dependency. The declaration is the same, simply replacing the previous one:
namespace WebApplication
{
public class ApplicationBootrapper : Nancy.DefaultNancyBootstrapper
{
protected override void ApplicationStartup(Nancy.TinyIoc.TinyIoCContainer container, Nancy.Bootstrapper.IPipelines pipelines)
{
base.ApplicationStartup(container, pipelines);
/* Enable cache using the IMemoryCacheStore, which uses the MsCaching Memory library, using the same key variations */
this.EnableRapidCache(container.Resolve<IRouteResolver>(), ApplicationPipelines, new[] { "query", "form", "accept" }, new IMemoryCacheStore());
}
}
}
RapidCache provides a small lib for integration with Redis, given that you provide a valid connection. It is provided as a separate package, so install it first via nuget:
PM> Install-Package Nancy.RapidCache.Redis
the usage is similar to the other stores:
using Nancy.RapidCache.CacheStore;
using Nancy.RapidCache.Extensions;
using Nancy.Routing;
namespace WebApplication
{
public class ApplicationBootrapper : Nancy.DefaultNancyBootstrapper
{
protected override void ApplicationStartup(Nancy.TinyIoc.TinyIoCContainer container, Nancy.Bootstrapper.IPipelines pipelines)
{
base.ApplicationStartup(container, pipelines);
/* Enable RapidCache using the RedisCacheStore, vary by url params id,query,takem, skip and accept header */
this.EnableRapidCache(container.Resolve<IRouteResolver>(), ApplicationPipelines, new[] { "query", "form", "accept" }, new RedisCacheStore("localhost"));
}
}
}
RapidCache also provides a small lib for a integration with Couchbase, given that you provide a valid Cluster object from the CouchbaseNetClient package and a bucket name that can be located. Install it via nuget:
PM> Install-Package Nancy.RapidCache.Couchbase
Once installed, we need to configure the cluster first, and then pass the cluster to the constructor:
using Nancy.RapidCache.CacheStore;
using Nancy.RapidCache.Extensions;
using Nancy.Routing;
namespace WebApplication
{
public class ApplicationBootrapper : Nancy.DefaultNancyBootstrapper
{
protected override void ApplicationStartup(Nancy.TinyIoc.TinyIoCContainer container, Nancy.Bootstrapper.IPipelines pipelines)
{
base.ApplicationStartup(container, pipelines);
var cluster = new Cluster(new ClientConfiguration
{
Servers = new List<Uri> { new Uri("http://127.0.0.1") }
});
var authenticator = new PasswordAuthenticator("user", "password");
cluster.Authenticate(authenticator);
/* Enable RapidCache using the CouchbaseCacheStore, vary by url params id,query,takem, skip and accept header */
/* Provide a bucket on the configuration */
this.EnableRapidCache(container.Resolve<IRouteResolver>(), ApplicationPipelines, new[] { "query", "form", "accept" }, new CouchbaseCacheStore(cluster, "myBucket")));
}
}
}
Define your own key per resolver that will help you cache to the level of granulatity you need.
using System;
using System.Text;
using Nancy;
using Nancy.RapidCache.Extensions;
using Nancy.Routing;
namespace WebApplication
{
public class ApplicationBootrapper : Nancy.DefaultNancyBootstrapper
{
protected override void ApplicationStartup(Nancy.TinyIoc.TinyIoCContainer container, Nancy.Bootstrapper.IPipelines pipelines)
{
base.ApplicationStartup(container, pipelines);
this.EnableRapidCache(container.Resolve<IRouteResolver>(), ApplicationPipelines, new UrlHashKeyGenerator());
}
public class UrlHashKeyGenerator : Nancy.RapidCache.CacheKey.ICacheKeyGenerator
{
public string Get(Request request)
{
using (var md5 = MD5.Create())
{
byte[] hash = md5.ComputeHash(Encoding.UTF8.GetBytes(request.Url.ToString()));
return Convert.ToBase64String(hash);
}
}
}
}
}
For more details please check the documentation.