Using Orchard caching to cache data for a length of time

You can use standard ASP.NET caching in Orchard, but it makes more sense to use Orchard's CacheManager service. It works better with tenants and I think it’s a bit nicer to use than the usual .NET way.

I needed to add caching to the driver of my weather module. It gets the weather data from the BBC. This information doesn’t change that often and it takes a while to get. So it made a lot of sense to cache it.

There are several ways to invalidate a cache, but in this case I just want my cached result to last for a certain amount of time.

To do this you’ll need an instance of ICacheManager and IClock to be injected into your class. In my case this is a driver class.

This is how you do that:

private ICacheManager _cacheManager;
private IClock _clock;

public MyWeatherDriver(ICacheManager cacheManager, IClock clock)
    _cacheManager = cacheManager;
    _clock = clock;

In my module WeatherType is an enum containing all the different descriptions the BBC use to describe weather. This includes WeatherType.Sand_storms, which I’ve not experienced yet.

I’ve separated the logic to load a cached WeatherType result into a separate method:

private WeatherType getCachedWeather(WeatherPart part)
    return _cacheManager.Get("weather" + part.City, ctx => {
        return getWeatherTypeFromBBC(part);

As you can see, you pass the cache manager a key to lookup. In my case this is the weather, and the city I’m looking at. You also pass it a function to use if it hasn’t got a valid cached response stored. In this function you setup a monitor to watch for the cache expiring. This is where I use IClock to wait for a TimeSpan of 20 minutes.

So, getCachedWeather will either return a cached result straight away if there is a cached result or will look up a new one from the BBC and cache that result for 20 minutes.

Restuta said

Good point, exactly what I was looking for.

Trevor Herr said

Thanks for this quick write up. Exactly what I needed.