Search code examples
c#inversion-of-controlunity-containerbreezehottowel

Breeze and Unity Container (HotTowel Angular + Breeze)


We're trying to create a delivery recipe based on HotTowel Angular + Breeze. The dependency injection part in the SPA app is well covered but trying to resolve the BreezeController through Unity proves to be a challenge. I may lack one thing in there but haven't figured it out.

So far here's what we've done:

  • Unity bootstrapper for ASP.NET MVC 3.5.1404 is installed
  • Added a new controller called LoggingController which applies the BreezeController attribute
  • On this controller set a repository dependency through the constructor

All's good and clean, Unity container is activated through UnityMvcActivator.cs which looks like this:

    using System.Linq;
    using System.Web.Mvc;
    using Microsoft.Practices.Unity.Mvc;

    [assembly: WebActivatorEx.PreApplicationStartMethod(typeof(CC.Web.App_Start.UnityWebActivator), "Start")]
    [assembly: WebActivatorEx.ApplicationShutdownMethod(typeof(CC.Web.App_Start.UnityWebActivator), "Shutdown")]

    namespace CC.Web.App_Start
    {
        /// <summary>Provides the bootstrapping for integrating Unity with ASP.NET MVC.</summary>
        public static class UnityWebActivator
        {
        /// <summary>Integrates Unity when the application starts.</summary>
        public static void Start() 
        {
            var container = UnityConfig.GetConfiguredContainer();
            FilterProviders.Providers.Remove(FilterProviders.Providers.OfType<FilterAttributeFilterProvider>().First());
            FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(container));

            DependencyResolver.SetResolver(new UnityDependencyResolver(container));

            // TODO: Uncomment if you want to use PerRequestLifetimeManager      
            Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule       (typeof(UnityPerRequestHttpModule));
        }

        /// <summary>Disposes the Unity container when the application is shut down.</summary>
        public static void Shutdown()
        {
            var container = UnityConfig.GetConfiguredContainer();
            container.Dispose();
        }
    }
}

The container is configured through UnityConfig.cs

using System;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using System.Web.Mvc;
using Microsoft.Practices.Unity.Mvc;
using System.Web.Http;

namespace CC.Web.App_Start
{
    /// <summary>
    /// Specifies the Unity configuration for the main container.
    /// </summary>
    public class UnityConfig
    {
        #region Unity Container
        private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
        {
            var container = new UnityContainer(); 
            RegisterTypes(container);
            return container;
        });

        /// <summary>
        /// Gets the configured Unity container.
        /// </summary>
        public static IUnityContainer GetConfiguredContainer()
        {
            return container.Value;
        }
        #endregion

        /// <summary>Registers the type mappings with the Unity container.</summary>
        /// <param name="container">The unity container to configure.</param>
        /// <remarks>There is no need to register concrete types such as controllers or API controllers (unless you want to 
        /// change the defaults), as Unity allows resolving a concrete type even if it was not previously registered.</remarks>
        public static void RegisterTypes(IUnityContainer container)
        {
            // NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
            container.LoadConfiguration();

            // TODO: Register your types here
            // container.RegisterType<IProductRepository, ProductRepository>();
        }
    }
}

Upon calling the controller it seems Unity is not in charge as it throws an error about not finding an empty constructor.

I would assume DependencyResolver.SetResolver(new UnityDependencyResolver(container)); would properly tell which resolver to use like in Mike Wasson blog post mentionned by Steve: config.DependencyResolver = new UnityResolver(container);. UnityDependencyResolver does implement IDependencyResolver.

So what I'm asking, assuming that installing the Nuget Package is only what is needed to hook Unity as a resolver, is there a way to use Unity as a Resolver for Breeze controllers or should we simply use the Breeze controllers as facade to a properly IOC built component? I'd rather have the resolving done through Unity transparently instead of going through a facade.


Solution

  • You will want the Unity.AspNet.WebApi package for resolving WebApi controllers (including Breeze controllers).

    You also need to tell WebApi to use Unity to resolve dependencies. Usually this is done in some static method that you call from Global.asax.cs. This blog post by Mike Wasson lays it all out.

    The Unity.WebAPI Github page suggests using the UnityConfig.RegisterComponents()method for registering your repositories.