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.
- using Spring.Context;
- using Spring.Context.Support;
- namespace SpringTestApplication
- {
- /// <summary>
- /// Spring Application Context.
- /// </summary>
- public static class SpringApplicationContext
- {
- private static IApplicationContext Context { get; set; }
- /// <summary>
- /// Returns a boolean value if the current application context contains an named object.
- /// </summary>
- /// <param name="objectName">Accepts the name of the object to check.</param>
- public static bool Contains(string objectName)
- {
- SpringApplicationContext.EnsureContext();
- return SpringApplicationContext.Context.ContainsObject(objectName);
- }
- /// <summary>
- /// Return a instance of an object in the context by the specified name.
- /// </summary>
- /// <param name="objectName">Accepts a string object name.</param>
- public static object Resolve(string objectName)
- {
- SpringApplicationContext.EnsureContext();
- return SpringApplicationContext.Context.GetObject(objectName);
- }
- /// <summary>
- /// Return a instance of an object in the context by the specified name and type.
- /// </summary>
- /// <typeparam name="T">Accepts the type of the object to resolve.</typeparam>
- /// <param name="objectName">Accepts a string object name.</param>
- public static T Resolve<T>(string objectName)
- {
- return (T)SpringApplicationContext.Resolve(objectName);
- }
- private static void EnsureContext()
- {
- if (SpringApplicationContext.Context == null)
- {
- SpringApplicationContext.Context = ContextRegistry.GetContext();
- }
- }
- }
- }
Once this is place you can then set up your custom controller factory to allow Spring.Net to manage your controllers.
- using System;
- using System.Web.Mvc;
- using System.Web.Routing;
- namespace SpringTestApplication
- {
- public class SpringControllerFactory : DefaultControllerFactory
- {
- /// <summary>
- /// Create the controller.
- /// </summary>
- /// <param name="requestContext">Accepts a <see cref="RequestContext"/>.</param>
- /// <param name="controllerName">Accepts a string controller name.</param>
- public override IController CreateController(RequestContext requestContext, string controllerName)
- {
- IController controller = null;
- string controllerClassName = string.Format("{0}Controller", controllerName);
- if (SpringApplicationContext.Contains(controllerClassName))
- {
- controller = SpringApplicationContext.Resolve<IController>(controllerClassName);
- this.RequestContext = requestContext;
- }
- else
- {
- controller = base.CreateController(requestContext, controllerName);
- }
- return controller;
- }
- /// <summary>
- /// Releases the controller.
- /// </summary>
- /// <param name="controller">Accepts an <see cref="IController"/></param>
- public override void ReleaseController(IController controller)
- {
- IDisposable disposable = controller as IDisposable;
- if (disposable != null)
- {
- disposable.Dispose();
- }
- }
- }
- }
The controller factory is called from the Application_Start() method in the Global.asax file.
- using System.Web.Mvc;
- using System.Web.Routing;
- namespace SpringTestApplication
- {
- public class MvcApplication : System.Web.HttpApplication
- {
- public static void RegisterRoutes(RouteCollection routes)
- {
- routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
- routes.MapRoute(
- "Default",
- "{controller}/{action}/{id}",
- new { controller = "Home", action = "Index", id = "" }
- );
- }
- protected void Application_Start()
- {
- RegisterRoutes(RouteTable.Routes);
- ControllerBuilder.Current.SetControllerFactory(typeof(SpringControllerFactory));
- }
- }
- }
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> :
- <sectionGroup name="spring">
- <section name="context" type="Spring.Context.Support.WebContextHandler, Spring.Web"/>
- <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core"/>
- </sectionGroup>
Just underneath the </configsections> add the following section to start using DI on your objects :
- <spring>
- <context>
- <resource uri="config://spring/objects"/>
- </context>
- <objects xmlns="http://www.springframework.net">
- <object id="HomeController" type="SpringTestApplication.Controllers.HomeController, SpringTestApplication" singleton="false">
- <property name="TestProperty" value="This has been injected via Spring.Net"/>
- </object>
- </objects>
- </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