It is no secret that I am a huge supporter of IoC (Inversion of Control) and AOP (Aspect-oriented Programming), which is evident with several earlier posts focused on building Enterprise applications. My first IoC experience was a Java portal project, which implemented Spring for many enterprise services. My recent projects have been .NET, which include several Spring.NET and Castle implementations. When evaluating IoC products, Ninject and more recently Microsoft Unity have also been candidates. IoC is gaining Microsoft community acceptance, especially with the release of ASP.NET MVC 4 and improved support/integration. See previous article for more information on design patterns including Dependency Injection (DI), Single Responsibility Principle (SRP) and Separation of Concerns (SoC).

In this post, I will provide an overview of the MVC 4 Castle Windsor IoC and Castle Core Dynamic Proxy features. Gasp…after several articles and posts with Spring.NET? This is true, but every project should evaluate several IoC (also referred to as Dependency Injection) containers and select the one that fits.

I would recommend NuGet for packages, so you can simplify the management of 3rd party libraries and tools.

Once you create a new ASP.NET MVC 4 solution and add the Castle packages to your solution, we can start building the application framework and scaffolding. Since this is a quick-start for Castle IoC and AOP features, we’ll build the essential components for a working MVC 4 solution.

First, create a Framework folder for the IoC and AOP classes. I would recommend Framework or Core, which are descriptive names. I created a Windsor sub-folder, which indicates the items will be supporting the IoC and AOP. The next level is Installers and Interceptors at the same level, so the following is an example of the project structure.

Framework Folder Structure

First, we will create the boilerplate WindsorControllerFactory to handle the IoC plumbing. The following is a snippet of the code, which you can add to the Framework.Windsor folder.

01
using System;
02
using System.Web;
03
using System.Web.Routing;
04
using Castle.MicroKernel;
05
using System.Web.Mvc;
06
 
07
namespace Mvc4Castle.Framework.Windsor
08
{
09
    /// <summary>
10
    /// Castle Windsor MVC4 Controller Factory Implementation for IoC
11
    /// </summary>
12
    public class WindsorControllerFactory : DefaultControllerFactory
13
    {
14
        private IKernel _kernel;
15
 
16
        public WindsorControllerFactory(IKernel kernel)
17
        {
18
            _kernel = kernel;
19
        }
20
 
21
        public override void ReleaseController(IController controller)
22
        {
23
            _kernel.ReleaseComponent(controller);
24
        }
25
 
26
        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
27
        {
28
            if (controllerType == null)
29
            {
30
                throw new HttpException(404, string.Format("The Windsor Controller at path '{0}' could not be found.", requestContext.HttpContext.Request.Path));
31
            }
32
            return (IController)_kernel.Resolve(controllerType);
33
        }
34
    }
35
}

Next, we will create IWindsorInstaller implementations. The installers will register components or objects with the IoC container. Alternatively, you can choose XML-based configuration files to define the components/objects instructing the container on the “How” to instantiate. In our example, we will use the MVC controllers included in the starter project (e.g. HomeController).

01
using Castle.MicroKernel.Registration;
02
using Castle.Windsor;
03
using Castle.MicroKernel.SubSystems.Configuration;
04
using System.Web.Mvc;
05
using Mvc4Castle.Controllers;
06
 
07
namespace Mvc4Castle.Framework.Windsor.Installers
08
{
09
    /// <summary>
10
    /// Castle Windsor Controller responsible for registering classes managed by
11
    /// the IoC container.
12
    /// 
13
    /// This implementation registers all MVC Controllers (IController).
14
    /// </summary>
15
    public class ControllerInstaller : IWindsorInstaller
16
    {
17
        public void Install(IWindsorContainer container, IConfigurationStore store)
18
        {
19
            container.Register(Classes.FromThisAssembly()
20
                                .BasedOn<IController>()
21
                                .LifestyleTransient()
22
                                .ConfigureFor<HomeController>(c => c.DependsOn(Dependency.OnComponent("service", "MyServiceResource"))));
23
        }
24
    }
25
}

In this example, we are registering objects/components based on IController located in the current assembly. We are also configuring the HomeController and dependency injection of the service argument. We’ll explore additional options for registering objects/components in the container.

We also need to add the container to our start-up processes in the global.asax. The Application_Start and Application_End require some logic to handle this task.

01
    public class MvcApplication : System.Web.HttpApplication
02
    {
03
        private static IWindsorContainer _container;
04
 
05
        protected void Application_Start()
06
        {
07
            AreaRegistration.RegisterAllAreas();
08
 
09
            WebApiConfig.Register(GlobalConfiguration.Configuration);
10
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
11
            RouteConfig.RegisterRoutes(RouteTable.Routes);
12
            BundleConfig.RegisterBundles(BundleTable.Bundles);
13
            InjectContainer();
14
        }
15
 
16
        /// <summary>
17
        /// Create MVC4 Controller for Castle Windsor IoC container
18
        /// </summary>
19
        private static void InjectContainer()
20
        {
21
            _container = new WindsorContainer().Install(FromAssembly.This());
22
 
23
            var controllerFactory = new WindsorControllerFactory(_container.Kernel);
24
            ControllerBuilder.Current.SetControllerFactory(controllerFactory);
25
        }
26
 
27
        /// <summary>
28
        /// Destroy Castle Windsor IoC container
29
        /// </summary>
30
        protected void Application_End()
31
        {
32
            _container.Dispose();
33
        }
34
    }
35

You can add several installer implementations using the fluent API or XML-based configuration files, so you can organize your object/component definitions for the IoC container. Since we are following design patterns, we will introduce Dependency Injection/DIP practices to inject the object/component dependency via the controller constructor. The service will represent the business logic, which is responsible for orchestrating the calls to the data tier or other service objects to process the client request and return an appropriate result.

1
       private IService _service;
2
 
3
        public HomeController(IService service)
4
        {
5
            _service = service;
6
        }

So…let’s take a look at a few container registration options. The following will register all objects/components with a type ending in “Service” (i.e. wildcard Service) from the current assembly. The life-cycle can also be configured, which in the examples ”transient” indicates a new instance.

1
           container.Register(Classes.FromThisAssembly()
2
                 .Where(type => type.Name.EndsWith("Service"))
3
                 .WithServiceDefaultInterfaces()
4
                 .Configure(c => c.LifestyleTransient().Interceptors<ServiceTitleInterceptor>()));
5

We’ll cover the AOP or dynamic proxies, which is the Interceptor. The following example defines the dependency using a named value, so the “Title” property will be set to the static value “Injected By Dependency Value”.

1
            container.Register(Component.For<IService>()
2
                .ImplementedBy<HomeService>()
3
                .Named("MyServiceValue")
4
                .DependsOn(Dependency.OnValue("Title", "Injected By Dependency Value"))
5
                .LifestyleTransient());
6

The next example is injecting the “Title” property value from the web.config appsettings “Title” parameter.

1
            container.Register(Component.For<IService>()
2
                .ImplementedBy<HomeService>()
3
                .Named("MyServiceConfig")
4
                .DependsOn(Dependency.OnAppSettingsValue("Title", "Title"))
5
                .LifestyleTransient());
6

The following illustrates injecting a property value from a resource file, which also is the “Title” property. This provides several source options for the dependency injection, which can also include a named component (see Named).

1
            container.Register(Component.For<IService>()
2
                .ImplementedBy<HomeService>()
3
                .Named("MyServiceResource")
4
                .DependsOn(Dependency.OnResource<App_LocalResources.Resource1>("Title", "Title"))
5
                .LifestyleTransient());
6

The previous examples introduce the Castle Windsor IoC basics as they apply to MVC4. The last topic is AOP, which we encountered with the interceptor in a previous object/component container registration. The Spring.NET AOP support was introduced in a previous post. Castle core is a lighter version, which is based on implementing the Castle.DynamicProxy.IInterceptor.

01
    public class ServiceTitleInterceptor : IInterceptor
02
    {
03
        public void Intercept(IInvocation invocation)
04
        {
05
            if (invocation.Method.Name.Equals("get_Title"))
06
                invocation.ReturnValue = "You have been hijacked at." + DateTime.Now;
07
            else
08
                invocation.Proceed();
09
        }
10
     }

In this interceptor implementation, the Intercept method contains logic to check for the method name “get_Title”. This is a Title property getter. If true then ReturnValue is set to “You have been hijacked at.” including a date-stamp. If the method name is not “get_Title” then the control is returned to the intercepted object and processing continues. You can implement an interceptor for logging, caching, transaction management, error handling and other common services without adding code to every class and method.

The following is an installer snippet for registering an object/component using the ServiceTitleInterceptor interceptor, so every call will be intercepted and the Intercept method executed.

1
.Interceptors<ServiceTitleInterceptor>()

The above will apply the ServiceTitleInterceptor to the object/component. You can also add the InterceptorAttribute ( [Interceptor(typeof(ServiceTitleInterceptor))] ) to the target class, which is an alternative to the fluent API approach above.

01
using Castle.Core;
02
using Mvc4Castle.Framework.Windsor.Interceptors;
03
 
04
namespace Mvc4Castle.Framework.Services
05
{
06
    [Interceptor(typeof(ServiceTitleInterceptor))]
07
    public class HomeService : IService
08
    {
09
        public string Title { get; set; } 
10
    }
11
}

I hope this quick-start provides another IoC and AOP option for your MVC projects. Since I was evaluating several IoC libraries for a current project, I thought a summary could be helpful.

Related Posts:

Sping.NET IoC

Spring.NET and MVC3

Spring.NET AOP