In my last post, I mentioned why I use Autofac with ASP.NET MVC, and how to set up a basic configuration. In this post, I will explain how to create an Autofac module that can be used to switch between different caching implementations.
Why Use Autofac Modules?
One of the great things about Autofac modules, is they provide an easy way to configure the IoC container from an XML file. For example, we could create a CacheModule which can load either a LocalCache, AzureCache or AppFabricCache, depending on a configuration flag in an XML file.
In the following example I will show you how this can be achieved.
Set up the Project
First of all create a new ASP.NET Web Application (MVC with no authentication) called CacheExample, and then run the following commands at the package manager console:
Install-Package Autofac.Mvc5
Install-Package Autofac.Configuration
The first command adds the Autofac IoC container to the project and the second command adds the ability to load modules using configuration files.
Create the ICache Interface
Create the following ICache interface and add it to the root of the project.
public interface ICache
{
void Clear();
object Get(string key);
void Remove(string key);
void Store(string key, object value, int minutesValidFor);
}
This is the interface that all cache implementations will need to implement.
Create LocalCache Implementation
Create a new class called LocalCache and add it to the root of the project. Make it implement ICache like the following:
public class LocalCache : ICache
{
public object Get(string key)
{
return HttpRuntime.Cache.Get(key);
}
public void Store(string key, object value, int minutesValidFor)
{
HttpRuntime.Cache
.Insert(
key,
value,
null,
Cache.NoAbsoluteExpiration,
TimeSpan.FromMinutes(minutesValidFor),
CacheItemPriority.Normal,
ItemRemoved);
}
public void Remove(string key)
{
HttpRuntime.Cache.Remove(key);
}
public void Clear()
{
var enumerator = HttpRuntime.Cache.GetEnumerator();
while (enumerator.MoveNext())
{
HttpRuntime.Cache.Remove(enumerator.Key.ToString());
}
}
private void ItemRemoved(string key, object value, CacheItemRemovedReason reason)
{
//TODO: Log removal
}
}
The above implementation uses the System.Web.Caching.Cache and is useful for single instance deployments.
Create NullCache Implementation
Create a NullCache class with the following implementation:
public class NullCache : ICache
{
public void Clear()
{
}
public object Get(string key)
{
return null;
}
public void Remove(string key)
{
}
public void Store(string key, object value, int minutesValidFor)
{
}
}
The NullCache implementation does nothing. We will use this to demonstrate switching between implementations by using either Local or None in the configuration file.
Create CacheModule
Create a new class called CacheModule and add it to the root of the project.
public enum CacheType
{
Local,
None,
}
public class CacheModule : Module
{
public CacheType CacheType { get; set; }
protected override void Load(ContainerBuilder builder)
{
if (CacheType == CacheType.Local)
{
builder.RegisterType<LocalCache>().As<ICache>().InstancePerDependency();
}
else
{
builder.RegisterType<NullCache>().As<ICache>().InstancePerDependency();
}
}
}
The CacheModule is quite basic. All it does is register the implementation in the Load method depending on what enum value is specified in the Web.config file. Here, we have either Local or None to switch between the LocalCache or NullCache implementations. If you want to add a new implementation, you would add a new enum value and then modify the if statement.
Register the Container and CacheModule with MVC
Add the following code to the Global.asax file at the top of the Application_Start method:
var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());
// register modules
builder.RegisterModule(new ConfigurationSettingsReader("autofac"));
DependencyResolver.SetResolver(new AutofacDependencyResolver(builder.Build()));
This will create the IoC container, register controllers for constructor injection, register the CacheModule and assign the IoC container as the MVC dependency resolver.
Add Configuration Option to Web.config
First of all, add an autofac configuration section name to the beginning of the <configuration>
<configuration>
<configSections>
<section name="autofac" type="Autofac.Configuration.SectionHandler, Autofac.Configuration" />
</configSections>
Now add the autofac configuration section just below the <configSections>
<autofac defaultAssembly="CacheExample">
<modules>
<module type="CacheExample.CacheModule">
<properties>
<property name="CacheType" value="Local" />
</properties>
</module>
</modules>
</autofac>
Changing the CacheType property value from Local to None will turn caching off. Now lets modify the HomeController to demonstrate caching.
Modify HomeController
Modify the home controller to look like the following example:
public class HomeController : Controller
{
private readonly ICache _cache;
public HomeController(ICache cache)
{
_cache = cache;
}
public ActionResult Index()
{
var cache = _cache.Get("HelloWorld") as string;
if (cache == null)
{
cache = string.Format("HelloWorld at: {0}", DateTime.UtcNow);
_cache.Store("HelloWorld", cache, 1);
}
return Content(cache);
}
}
The HomeController has been modified to inject the either NullCache or LocalCache depending on what was specified in the Web.config file. The Index action has been modified to load a string containing the DateTime from cache. When the Cache is turned off a new Hello World string will be generated each time you refresh the page. When the LocalCache is used a new string will be generated every minute or so.
Now run the project with both settings and watch the caching in action. You should now be able to extend this for use with Azure or AppFabric caching.
And that’s a basic overview of Autofac modules in action. You can download this example project Here