Set up Spring.Net IoC with ASP.Net MVC

There are a number of steps required for setting up Spring.Net IoC with ASP.Net MVC and it can be a little tricky getting it up and running the first time so I thought I’d document a basic working set up.

The first step is to make sure you’re including the necessary assemblies (I’m using version 1.2 for this example) :

For this set up you will need at least the following referenced:

  • Spring.Core
  • Spring.Data
  • Spring.Web
  • Spring.WebExtensions

Once referenced the first step is to create a class to handle the Spring.Net application context.

 

  1. using Spring.Context;
  2. using Spring.Context.Support;
  3. namespace SpringTestApplication
  4. {
  5.     /// <summary>
  6.     /// Spring Application Context.
  7.     /// </summary>
  8.     public static class SpringApplicationContext
  9.     {
  10.         private static IApplicationContext Context { get; set; }
  11.         /// <summary>
  12.         /// Returns a boolean value if the current application context contains an named object.
  13.         /// </summary>
  14.         /// <param name="objectName">Accepts the name of the object to check.</param>
  15.         public static bool Contains(string objectName)
  16.         {
  17.             SpringApplicationContext.EnsureContext();
  18.             return SpringApplicationContext.Context.ContainsObject(objectName);
  19.         }
  20.         /// <summary>
  21.         /// Return a instance of an object in the context by the specified name.
  22.         /// </summary>
  23.         /// <param name="objectName">Accepts a string object name.</param>
  24.         public static object Resolve(string objectName)
  25.         {
  26.             SpringApplicationContext.EnsureContext();
  27.             return SpringApplicationContext.Context.GetObject(objectName);
  28.         }
  29.         /// <summary>
  30.         /// Return a instance of an object in the context by the specified name and type.
  31.         /// </summary>
  32.         /// <typeparam name="T">Accepts the type of the object to resolve.</typeparam>
  33.         /// <param name="objectName">Accepts a string object name.</param>
  34.         public static T Resolve<T>(string objectName)
  35.         {
  36.             return (T)SpringApplicationContext.Resolve(objectName);
  37.         }
  38.         private static void EnsureContext()
  39.         {
  40.             if (SpringApplicationContext.Context == null)
  41.             {
  42.                 SpringApplicationContext.Context = ContextRegistry.GetContext();
  43.             }
  44.         }
  45.     }
  46. }

Once this is place you can then set up your custom controller factory to allow Spring.Net to manage your controllers.

  1. using System;
  2. using System.Web.Mvc;
  3. using System.Web.Routing;
  4. namespace SpringTestApplication
  5. {
  6.     public class SpringControllerFactory : DefaultControllerFactory
  7.     {
  8.         /// <summary>
  9.         /// Create the controller.
  10.         /// </summary>
  11.         /// <param name="requestContext">Accepts a <see cref="RequestContext"/>.</param>
  12.         /// <param name="controllerName">Accepts a string controller name.</param>
  13.         public override IController CreateController(RequestContext requestContext, string controllerName)
  14.         {
  15.             IController controller = null;
  16.             string controllerClassName = string.Format("{0}Controller", controllerName);
  17.             if (SpringApplicationContext.Contains(controllerClassName))
  18.             {
  19.                 controller = SpringApplicationContext.Resolve<IController>(controllerClassName);
  20.                 this.RequestContext = requestContext;
  21.             }
  22.             else
  23.             {
  24.                 controller = base.CreateController(requestContext, controllerName);
  25.             }
  26.             return controller;
  27.         }
  28.         /// <summary>
  29.         /// Releases the controller.
  30.         /// </summary>
  31.         /// <param name="controller">Accepts an <see cref="IController"/></param>
  32.         public override void ReleaseController(IController controller)
  33.         {
  34.             IDisposable disposable = controller as IDisposable;
  35.             if (disposable != null)
  36.             {
  37.                 disposable.Dispose();
  38.             }
  39.         }
  40.     }
  41. }

The controller factory is called from the Application_Start() method in the Global.asax file.

 

  1. using System.Web.Mvc;
  2. using System.Web.Routing;
  3. namespace SpringTestApplication
  4. {
  5.     public class MvcApplication : System.Web.HttpApplication
  6.     {
  7.         public static void RegisterRoutes(RouteCollection routes)
  8.         {
  9.             routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
  10.             routes.MapRoute(
  11.                 "Default",                                             
  12.                 "{controller}/{action}/{id}",                         
  13.                 new { controller = "Home", action = "Index", id = "" }  
  14.             );
  15.         }
  16.         protected void Application_Start()
  17.         {
  18.             RegisterRoutes(RouteTable.Routes);
  19.             ControllerBuilder.Current.SetControllerFactory(typeof(SpringControllerFactory));
  20.         }
  21.     }
  22. }

 

With this all in place, you now need to add a little configuration to tie it all together.

In the Web.config file add the following to the <configSections> :

  1.   <sectionGroup name="spring">
  2.       <section name="context" type="Spring.Context.Support.WebContextHandler, Spring.Web"/>
  3. <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core"/>
  4.   </sectionGroup>

Just underneath the </configsections> add the following section to start using DI on your objects :

  1. <spring>
  2.     <context>
  3.         <resource uri="config://spring/objects"/>
  4.     </context>
  5.     <objects xmlns="http://www.springframework.net">
  6.   
  7.         <object id="HomeController" type="SpringTestApplication.Controllers.HomeController, SpringTestApplication" singleton="false">
  8.             <property name="TestProperty" value="This has been injected via Spring.Net"/>
  9.         </object>
  10.   
  11.     </objects>   
  12. </spring>

As you can see, in this test case I’ve created a property on my HomeController class called TestProperty which has a string value injected via Spring.Net.

You can download the working solution here.

I hope this is useful.

Kind Regards,

Sean McAlinden

www.asp-net-mvc.com

7 Comments

  • Thanks for allowing us to download this demo app. I am working on an MVC project at the moment and it will be interesting to see how I can get IoC incorporated with it.

  • Hello,
    I've tried changing your project to ASP.NET MVC 2 RC
    But I keep getting:
    Error 1 'SpringTestApplication.SpringControllerFactory' does not contain a definition for 'RequestContext' and no extension method 'RequestContext' accepting a first argument of type 'SpringTestApplication.SpringControllerFactory' could be found (are you missing a using directive or an assembly reference?) C:\DEV\temp\SpringTestApplication\SpringControllerFactory.cs 22 22 SpringTestApplication
    Perhaps you may know what needs to be changed
    Thank You in advance

  • Hi Daniil,

    I haven't tried using it with MVC 2 RC but I am aware that there are some breaking changes in how the contexts work - if I get chance I'll have a go and post an update.

    cheers.

    Sean.

  • Hi Asma,
    Depends what you mean/need in your project, spring.net has quite a few functions in terms of DI, AOP, Transaction handling etc.
    Your best bet is to go to the Spring.Net site and take a look through some of the quick start tutorials.
    What I would say however, if you're new to DI, there are much easier frameworks out there than Spring - I would take a look at Structure Map, Linfu or Castle Windsor - you'll find a lot more tutorials on these.

    Cheers,

    Sean.

  • unfortunately, I'm obliged to use spring.net, so if there’s anu useful link, jut send me a message in twitter. thanks^^

  • @Daniil Harik: You can simply comment out or remove that line of code and it should work fine (it did for me). My only issue with Sean's code after that was at runtime when MVC tried to create a controller for favicon.ico, but that's an MVC setup issue. Adding the following ignoreroute in Global.asax.cs RegisterRoutes method solved the favicon.ico issue:

    routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?favicon.ico(/.*)?" });

    Thanks Sean - this post was very clear and easy to follow!

  • Thanks Emil.

Comments have been disabled for this content.