One of the challenges of any old Web Forms application is that it encouraged you to overlap concerns and abstractions. For example in old web form code you might be collecting data and also checking the thread for HttpContext details, all within the same method, making it almost impossible to reuse that code anywhere else.

This was certainly the case for the caching mechanism employed bythe RSS feed of DasBlog, I found that the data collection and the Caching were so intertwined that neither were useful or reusable outside of a Web Forms context. What that forced me to do was separate those concerns by pushing the code for the data collection behind a repository pattern, simultaneously it allowed me take advantage of some rather straightforward middleware caching at the Controller available in ASP.NET Core.

This allows my class, FeedController, to use dependency injection to pull in a reference to IMemoryCache and I assign that to a private member variable for use in any of my Actions (ISubscriptionRepository is simply where I am pulling data from):

So now we have the Memory Cache but in order to actually cache an object in memory for, let's say, 5 minutes we must define a key to both create and subsequently retrieve the cache object. In the following example then, the object last for 5 minutes, any request that comes in after that 5 minutes will be forced to retrieve and refresh the cache.

My Rss Action simply checks the cache based on a key (in this case RSS_CACHE_KEY), if I am successful retrieving the object I simply return it. However, if the object does not exist (new startup or cache has been released) I then am forced to retrieve the data from my repository layer and cache it. In the above example I set a sliding expiration time of 5 minutes to ensure that the data is not too stale. One interesting side note is that if your site is under memory pressure you could lose your cache without realizing it, forcing you to go back to your data source every time. You can circumvent this useful behavior by changing the cache priority to CacheItemPriority.NeverRemove.

That was fairly straightforward, caching is now removed from data retrieval and caching is conveniently, and correctly tied to the controllers.

As an aside one of the things that was not obvious to me is that HTTP responses in XML format are not enabled by default in ASP.NET Core. To actually produce an XML (RSS) response from any of your controller actions you need to explicitly add the middleware to support it. I used the Formatters.Xml nuget package as follows: