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