Mehfuz's WebLog

Live crazy, think different!

Sponsors

News

Passionate about cutting edge technologies and facinated by the modern web and phone revolution.Currently working at Telerik Corporation, the leading .net component vendor.
Follow me


Articles


Projects

Introducing AutoBox - On the fly dependency injection and caching container.

Just when we have dependencies for a controller, we need to wrap around our heads to write a bootstrapper that will dynamically inject dependencies for a controller in runtime and once we we want to do  data caching like a particular method in accounts repository need to get cached for a  certain number of time and it should invalidate when someone calls update, things get complex and may be we get around this with some attribute based solution.

autoboxLogo-medium

Therefore, I introduce to you AutoBox. It is a on the fly dependency injection and caching container. It dynamically injects dependencies based on convention. Also, let you cache repository calls to memcached (the most popular cross-platform caching system) which is originally implemented by LiveJournal and used by high volume site like Youtube.

Now getting started with AutoBox is simple.  Lets consider that you have a ProductController and the constructor looks something like:

 

  1. public ProductController(IProductRepository repository)
  2. {
  3.     this.repository = repository;
  4. }

ProductRepository is implemented in MyCoolWebSite.Repository folder where IProductRepository is under MyCoolWebSite.Repository.Abstraction (Not a required). In the global.ascx you first need to add the following line:

 

  1. Container.Init();

Here to mention that  AutoBox will do the mapping on demand thus making it lazy.

Next you need to override the GetControllerInstance from DefaultControllerFactory. Since AutoBox is implemented using CommonServiceLocator, therefore you can directly include ServiceLocator.Current.GetInstance that will return the target controller with dependencies properly injected.

 

  1. public class CustomControllerFactory : DefaultControllerFactory
  2. {
  3.     protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
  4.     {
  5.         return ServiceLocator.Current.GetInstance(controllerType) as IController;
  6.     }
  7. }

 

Finally, at the end of global.ascx.cs you need to write the following line; so that all the controller get instance requests go through AutoBox:

 

  1. ControllerBuilder.Current.SetControllerFactory(new CustomControllerFactory());

 

Hit F5 and and you are ready to roll with dependencies.

 

Now, moving forward there is a method in IProuductRepository lets say IProductReposiroty.GetAllProducts(). You just dont want to hit database all the time, unless invalidated. Therefore, you can further specify (you can also combine that with your bootstrapper that registers routes and mappings using AutoMapper):

 

  1. Container.Setup<ProductRepository>(x => x.GetAllProducts()).Caches(TimeSpan.FromMinutes(1));

 

This tells AutoBox to cache the result of the call (using memcached) that will automatically invalidate after a minute. However you can explicitly specify the method that will invalidate it.

  1.  
  2. Container.Setup<ProductRepository>(x=> x.Create(Arg.Varies<Product>()).Invalidates(x => x.GetAllProducts());

 

You will notice here that I have used Arg.Varies{T}. Its similar to VaryByParams in output cache where it tells the tool to invalidate  based on the variable argument value. Finally to make Memcached working you will need to have the following block in web.config (will be added automatically when installed from NuGet [Yes its NuGet]).

 

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <configuration>
  3.  
  4.   <configSections>
  5.     <section name="autoBox" type="AutoBox.AutoBoxSection, AutoBox" />
  6.   </configSections>
  7.  
  8.   <autoBox cacheStore="localhost" cacheProvider="MemcachedProvider" />
  9.  
  10. </configuration>

 

Here you will notice that by default its pointing to localhost and MemcachedProvider. However it can be an external IP pointing to Amazon ElastiCache (released a few weeks ago).Here to note that memcached is a caching mechanism and therefore the tool is agnostic of any underlying cloud service that you may use.

To test caching locally, you can use the CouchBase’s Membase server (Not limited to), it gives you a nice web based GUI to monitor the cache usage, configure memory and clusters.

You can download it from this link:

http://www.couchbase.com/products-and-services/memcached/

 

You can get more information on this project, download source and contribute at the following URL:

http://mehfuzh.github.com/AutoBox/

 

As mentioned above, it is also possible to use the tool with a hand-rolled bootstrapper that uses IOC container (Ex. Ninject) and AutoMapper  and can save you some lines in binding the controller dependencies and if you want to use high-performance caching mechanism like memcached and don’t  want to pull your hair off on how to invalidate a repository call when saved a part of it then this tool can give you a boost.

 

Hope that helps

Comments

Romi said:

Great, but can you explain more about multiserver options like AWS and implementations samples.

# December 7, 2011 8:32 AM

mehfuzh said:

Hi Romi,

I am not sure what you mean by multiserver options.But generally memcached load can be configured in the server (eg.amazon elasticcache). In terms of adding muiliple server endpoints i will take a look.

Cheers,

Mehfuz

# December 22, 2011 4:26 AM