Keith Burnell and I will be hosting an Azure and MVC Boot Camp on Friday, June 22nd, 2012 at UW-Fox Valley. You can register at http://azureandmvcbootcamp.eventbrite.com/.

Azure and MVC Boot Camp

Spend a day with some of the nation’s leading web and cloud experts building an ASP.NET MVCweb application that runs in Windows Azure and hosts data in SQL Azure and/or Azure Storage. Together we will build an ASP.NET MVC web application using Razor, jQuery and OData that will be hosted in Windows Azure using several of Azure’s service offerings. We will explore web roles, cloud storage, SQL Azure, and common scenarios. We will show you how to sign up for free time in the cloud and even cover what should not be moved to cloud.

We will save time for open Q&A.

This will be a hands-on event where you will need a laptop configured with the required pieces.

Lunch and prizes will be provided.

ACTION ITEMS PRIOR TO ATTENDING THE EVENT to make the best use of your time at the Windows Azure/ASP.NET MVC Kick Start Event, you must prepare the following requirements before the event:

* WiFi will be accessible on campus, but please download the prerequisites prior to the event.

* Power jacks are available on the top of each desk.

ASP.NET MVC3 has built in mechanisms to support an Inversion of Control container for the framework. Let us look at how to use StructureMap and tie it into MVC3’s framework for use with providing Controller classes as well as how we would normally use it to provide our custom classes.

If you’re using NuGet, you’ll find it automatically includes a reference to WebActivator, which is something that allows for calling startup code without having to edit the global.asax file. This post is for those that don’t want to use WebActivator for whatever reason.

Inside of the global.asax file add a method to perform the container initialization.

		private static void InitializeContainer()
		{
			// Configure IoC 
			DependencyRegistrar.EnsureDependenciesRegistered();

			StructureMapDependencyResolver structureMapDependencyResolver = new StructureMapDependencyResolver();
			DependencyResolver.SetResolver(structureMapDependencyResolver);
		}

In the first bit of code, the DependencyRegistrar class contains configures StructureMap once and only once.

		public static void EnsureDependenciesRegistered()
		{
			if (alreadyRegistered)
			{
				return;
			}

			lock (SyncronizationLock)
			{
				if (alreadyRegistered)
				{
					return;
				}

				RegisterDependencies();
				alreadyRegistered = true;
			}
		}

		private static void RegisterDependencies()
		{
			ObjectFactory.Initialize(
				x => x.Scan(
					scan =>
						{
							scan.TheCallingAssembly();
							scan.WithDefaultConventions();
							scan.LookForRegistries();
						}));
#if DEBUG
			// Place a breakpoint on the line and see the configuration of StructureMap.
			string configuration = ObjectFactory.WhatDoIHave();
#endif
		}

The line in the InitializeContainer method instantiates an instance of the StructureMapDependencyResolver class.  This class implements the MVC frameworks IDependencyResolver interface, which is how StructureMap will interact with the MVC DependencyResolver.

	public class StructureMapDependencyResolver : IDependencyResolver
	{
		#region Implementation of IDependencyResolver

		/// <summary>
		/// Resolves singly registered services that support arbitrary object creation.
		/// </summary>
		/// <returns>
		/// The requested service or object.
		/// </returns>
		/// <param name="serviceType">The type of the requested service or object.</param>
		public object GetService(Type serviceType)
		{
			if (serviceType == null)
			{
				return null;
			}

			try
			{
				return ObjectFactory.GetInstance(serviceType);
			}
			catch
			{
				return null;
			}
		}

		/// <summary>
		/// Resolves multiply registered services.
		/// </summary>
		/// <returns>
		/// The requested services.
		/// </returns>
		/// <param name="serviceType">The type of the requested services.</param>
		public IEnumerable<object> GetServices(Type serviceType)
		{
			return ObjectFactory.GetAllInstances(serviceType).Cast<object>();
		}

		#endregion
	}

At this point, your Controller classes will be provided using StructureMap. Not too bad! In order to use it for other types of injection, just go about it in the same process as usual. You can see below the use of injecting an ILog implementation. In the source code you can see that I use log4Net and a StructureMap Registry class.

	[HandleError]
    public class DemoController : Controller
    {
        private static ILog log;

        /// <summary>
        /// Initializes a new instance of the <see cref="DemoController"/> class. 
        /// </summary>
        /// <param name="injectedLog">
        /// ILog implementation injected from the IoC container
        /// </param>
        public DemoController(ILog injectedLog)
        {
            log = injectedLog;
        }

		public ActionResult Index()
		{
			log.Debug("The default page has been requested!");
			return View();
		}
    }

I wanted to make sure that my HttpScoped objects are disposed of when the request ends, so I also added a call to the built in StructureMap method ReleaseAndDisposeAllHttpScopedObjects.

		protected void Application_EndRequest(object sender, EventArgs e)
		{
			ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects();
		}

Not too much code in order to get the full power out of StructureMap with ASP.NET MVC.

Tools Used:

  • Visual Studio 2010
  • StructureMap 2.6.3.0
  • ASP.NET MVC3
  • NuGet
  • log4Net 1.2.11.0

Download the Source:

StructureMap MVC3 Demo

Followin Up Reading on the Service Locator Anti-Pattern/Code Smell