I am migrating a MonoRail application to ASP.NET MVC 1.0. In my original application I wrote a custom cache provider (a distributed cache provider using memcached). In MonoRail this task was very easy because the framework used interfaces and there is ICacheProvider that looks like this:
public interface ICacheProvider : IProvider, IMRServiceEnabled
{
void Delete(string key);
object Get(string key);
bool HasKey(string key);
void Store(string key, object data);
}
An instance of this interface is available in every controller action. So, all I had to do was to implement a custom cache provider that uses memcached and tell MonoRail to use my cache provider instead of the default one. It was also very easy to mock and unit test my controller.
In ASP.NET MVC 1.0 there's the System.Web.Abstractions assembly (name looks promising) that defines the HttpContextBase like this:
public abstract class HttpContextBase : IServiceProvider
{
...
public virtual System.Web.Caching.Cache Cache { get; }
...
}
I don't understand how the Cache property used here is an abstraction of a cache provider. It is the legacy sealed Cache class. It seems that I am not the only one struggling to mock out the classes in the framework.
I am very new to the ASP.NET MVC framework and I must be missing something here. I could write a CustomBaseController that uses an ICacheProvider interface that I define and all my controllers derive from this base class, but if there's a more elegant (ASP.NET MVCish) solution I would be glad to implement it. I've noticed that HttpContextBase implements IServiceProvider. Where's the GetService method going to look for services? Can this be easily mocked?
Cache doesn't have an official abstraction or provider, but you can easily build one:
ASP.NET 4.0 includes an output cache provider abstraction (AFAIK not a general cache abstraction but only for output caching)