For those of you who doesnt know about DI ( dependency injection ) or IOC (Inversion of Control), I suggest you
have a look at this blog post written by Phil Haack http://haacked.com/archive/2007/12/07/tdd-and-dependency-injection-
with-asp.net-mvc.aspx. For me, on every single MVC project that I have done, this practice is always a must-
have one that I recommend. There are plenty of choices out there for you to choose and the one that I have
always used the most was structure map that Phil haved mentioned above. However, in one of the recent project, I
was trying to implementing IOC using windsor since I found it quite interesting.
For this, I have been googling around like always and this article has got most of my attention since I just
dont like dealing with xml configuration , http://blog.andreloker.de/post/2009/03/28/ASPNET-MVC-with-
Windsor-programmatic-controller-registration.aspx. There were couple of more articles that was related to the
same subject if you do some more googling, however most of them was used in aspnet mvc 1 and things has changed.
Therefore I got to try implementing a bit and bob from each source of information to come up with the solution
that I found most appropriate for my aspnet mvc 2 application. So here it goes:
1. First step:
Go to this link http://www.castleproject.org/castle/download.html,
and download the release under windsor, after extract the castle-windsor zip file, you just need to add the
following files in the bin folder to your project:
Castle.Core.dll
Castle.DynamicProxy2.dll
Castle.MicroKernel
Castle.Windsor.dll
2. Second Step:
We need to create custom Controller Factory class, create a new .cs file and called it .i.e
WindsorControllerFactory.cs. Here is the code for this class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Castle;
using Castle.Core;
using Castle.Windsor;
using Castle.MicroKernel;
using System.Reflection;
using Castle.MicroKernel.ComponentActivator;
using Castle.MicroKernel.Registration;
namespace YOurProject.Infrastructure
{
public class WindsorControllerFactory : DefaultControllerFactory
{
readonly IWindsorContainer container;
public WindsorControllerFactory(IWindsorContainer container) {
this.container = container;
}
protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type
controllerType) {
return (IController)this.container.Resolve(controllerType);
}
}
}
3. Third step
Now we just need to add more code to the Global.asax file for the web site to use our controller factory instead
of the default one. Here is all the code in this file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Castle;
using Castle.Core;
using Castle.Windsor;
using Castle.MicroKernel;
using YourProject.Infrastructure;
using System.Reflection;
using Castle.MicroKernel.ComponentActivator;
using Castle.MicroKernel.Registration;
namespace YorProject.Web
{
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
// visit http://go.microsoft.com/?LinkId=9394801
public class MvcApplication : System.Web.HttpApplication
{
static IWindsorContainer container;
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });
//routes.MapRoute(
// "Default", // Route name
// "{controller}/{action}/{id}", // URL with parameters
// new { controller = "Home", action = "Index", id = "" } // Parameter defaults
//);
routes.MapRoute("Default", // Route name
"{controller}/{action}/{id}",
new
{
controller = "Home",
action = "Index",
id = ""
}); // Parameter defaults )
}
//this is for the windsor
//static void CreateWindsorContainer()
//{
// container = new WindsorContainer();
//}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
CreateWindsorContainer();
RegisterControllers();
RegisterControllerFactory();
}
static void RegisterControllers()
{
//this is to find all the class that implement icontroller interface
IEnumerable<Type> controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes()
where typeof(IController).IsAssignableFrom(t)
select t;
//now add component life style for these classes
//transient is used since a controller can be used multiple times
foreach (Type t in controllerTypes)
container.AddComponentLifeStyle(t.FullName, t, LifestyleType.Transient);
//these are to register the component that we used for the controllers
container.Register( Component.For<your repository interface>().ImplementedBy< the class of the
repository that you used for this kind of interface >().LifeStyle.Transient);
}
//this is to register the controller factory without using xml configuration
static void RegisterControllerFactory()
{
container.Register(
Component
.For<IControllerFactory>()
.ImplementedBy<WindsorControllerFactory>()
.LifeStyle.Singleton
);
var controllerFactory = container.Resolve<IControllerFactory>();
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
}
static void CreateWindsorContainer()
{
if (container == null)
{
container = new WindsorContainer();
container.Register(
Component
.For<IWindsorContainer>()
.Instance(container)
);
}
}
}
}
That is it, now you have windsor implemented in your aspnet mvc project. Hope you find this useful