Self Host WebApi with Owin and Unity

Using Unity together with a WebApi application and OWIN Hosting is a little bit more complicated compared to the standard WebApi and Unity.

This blog shows how to host ASP.NET Web API in a console application, using OWIN to self-host the Web API framework and Unity as an IoC.

The following steps need to be implemented:

  1. OWIN.Hosting and Unity assemblies must be added to the solution
  2. The Unity registrations and Unity startup logic are required
  3. A Unity resolver needs to be added to the OWIN startup context
  4. The Dispose logic must be implemented where required.

To add the OWIN.Hosting logic, use the following nuget package:
http://www.nuget.org/packages/Microsoft.AspNet.WebApi.OwinSelfHost/

Install-Package Microsoft.AspNet.WebApi.OwinSelfHost -Pre

Use the nuget manager to add the Unity logic.
UnityNugetWebApi

Now a start method is required which can be called by the console application or a windows service. This method resolves the Startup instance using unity. The method also defines the server url and starts the service using the OWIN configuration method.

using Owin; 
using System.Web.Http;
using Microsoft.Owin.Hosting;
using System;
using System.Net.Http;
using Microsoft.Practices.Unity;

namespace SelfHostWebApiOwin
{
    public class Startup
    {
        private static readonly IUnityContainer _container = UnityHelpers.GetConfiguredContainer();

        public static void StartServer()
        {
            string baseAddress = "http://localhost:8081/";
            var startup = _container.Resolve<Startup>();
            IDisposable webApplication = WebApp.Start(baseAddress, startup.Configuration);

            try
            {
                Console.WriteLine("Started...");

                Console.ReadKey();
            }
            finally
            {
                webApplication.Dispose();
            }
        }        
    }
}

The Configuration(IAppBuilder appBuilder) provides all the information required for our service. This is where authorization, filters, http logging, other owin clients would be added.

 public void Configuration(IAppBuilder appBuilder) 
{ 
  // Configure Web API for self-host. 
  HttpConfiguration config = new HttpConfiguration();
  config.DependencyResolver = new UnityDependencyResolver(
      SelfHostWebApiOwin.UnityHelpers.GetConfiguredContainer());

  config.Routes.MapHttpRoute( 
                name: "DefaultApi", 
                routeTemplate: "api/{controller}/{id}", 
                defaults: new { id = RouteParameter.Optional } 
            ); 

  appBuilder.UseWebApi(config); 
}

In this method, the HttpConfiguration.DependencyResolver is set to a UnityDependencyResolver instance. This is required so that contructor injection can be used in the webApi controllers. The UnityDependencyResolver class is exactly the same as the Unity.WebApi.UnityDependencyResolver class. Unity.WebApi is not used because this is a self hosted OWIN application.

http://unity.codeplex.com/SourceControl/latest#Unity/Unity.WebApi/Src/UnityDependencyResolver.cs

UnityDependencyResolver : IDependencyResolver

The unity registrations need to be defined. This is defined in the UnityHelper class. The instances are registered using the Registration by Convention. Attributes are used so that each interface, class lifetime register type can be defined at ease. No need for configuration hell.

using System;
using System.Collections.Generic;
using System.Reflection;
using Microsoft.Practices.Unity;
using System.Linq;
using SelfHostWebApiOwin.Business.Attributes;
using SelfHostWebApiOwin;

namespace SelfHostWebApiOwin
{
    public static class UnityHelpers
    {
        #region Unity Container
        private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
        {
            var container = new UnityContainer();
            RegisterTypes(container);
            return container;
        });

        public static IUnityContainer GetConfiguredContainer()
        {
            return container.Value;
        }
        #endregion

        //private static readonly Type[] EmptyTypes = new Type[0];

        public static IEnumerable<Type> GetTypesWithCustomAttribute<T>( Assembly[] assemblies)
        {
            foreach (var assembly in assemblies)
            {
                foreach (Type type in assembly.GetTypes())
                {
                    if (type.GetCustomAttributes(typeof(T), true).Length > 0)
                    {
                        yield return type;
                    }
                }
            }
        }

        public static void RegisterTypes(IUnityContainer container)
        {
            var myAssemblies = AppDomain.CurrentDomain.GetAssemblies().Where(a => a.FullName.StartsWith("SelfHostWebApiOwin")).ToArray();

            container.RegisterType(typeof(Startup));

            container.RegisterTypes(
                UnityHelpers.GetTypesWithCustomAttribute<UnityIoCContainerControlledAttribute>(myAssemblies),
                WithMappings.FromMatchingInterface,
                WithName.Default,
                WithLifetime.ContainerControlled,
                null
                ).RegisterTypes(
                         UnityHelpers.GetTypesWithCustomAttribute<UnityIoCTransientLifetimeAttribute>(myAssemblies),
                         WithMappings.FromMatchingInterface,
                         WithName.Default,
                         WithLifetime.Transient);

        }

    }
}

Here’s an example of an attribute.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace SelfHostWebApiOwin.Business.Attributes
{
    [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Struct)]
    public class UnityIoCTransientLifetimeAttribute : System.Attribute
    {
        public double version;

        public UnityIoCTransientLifetimeAttribute()
        {
            version = 1.0;
        }
    }
}

Now the business layer can be created. I use only constructor injection in this layer. These classes have loose coupling and can easily be tested.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using SelfHostWebApiOwin.Business.Logging;
using SelfHostWebApiOwin.Business.Attributes;

namespace SelfHostWebApiOwin.Business
{
    [UnityIoCTransientLifetimeAttribute]
    public class BusinessClass : IBusinessClass
    {
        private IUnitOfWorkExample _unitOfWorkExample;

        public BusinessClass(IUnitOfWorkExample unitOfWorkExample)
        {
            _unitOfWorkExample = unitOfWorkExample;
            UnityEventLogger.Log.CreateUnityMessage("BusinessClass");
        }

        private bool _disposed = false;

        public string Hello()
        {
            return _unitOfWorkExample.HelloFromUnitOfWorkExample();
        }

        public void Dispose()
        {
            _unitOfWorkExample.Dispose();
            UnityEventLogger.Log.DisposeUnityMessage("BusinessClass");
            if (!_disposed)
            {
                _disposed = true;
            }
        }
    }
}

And now the business layer can be added to the controllers as required using construction injection.

public class ValuesController : ApiController
    {
        private readonly IBusinessClass _businessClass;
        private readonly IBusinessClass2 _businessClass2;
        public ValuesController(IBusinessClass businessClass, IBusinessClass2 businessClass2)
        {
            _businessClass = businessClass;
            _businessClass2 = businessClass2;
        }

When the sample application is started, fiddler can be use to access the api. We can see from the result that the business methods are used and the application functions as defined.

fillderDebugWebApi

Code: https://github.com/damienbod/SelfHostWebApiWithOwinAndUnity

What’s missing:

  • We have no proper dispose logic implemented. We could do this by implementing a new LifeTime Manager (per request as implemented in Unity.MVC) with a dispose.
  • We could also create a filter provider. Unity.MVC also provides a good example.
  • We could create a nuget packet Unity.SelfHostWebApi with all of this in it…

Links:
http://www.asp.net/web-api/overview/hosting-aspnet-web-api/use-owin-to-self-host-web-api

http://code-inside.de/blog-in/2013/09/15/owin-katana-one-asp-net/

http://channel9.msdn.com/Shows/Web+Camps+TV/The-Katana-Project-OWIN-for-ASPNET

http://unity.codeplex.com/

http://www.asp.net/web-api

http://stackoverflow.com/questions/6121050/mvc-3-unity-2-inject-dependencies-into-a-filter

http://www.techbubbles.com/aspnet/what-is-katana-and-owin-for-asp-net/

http://www.asp.net/posters/web-api/ASP.NET-Web-API-Poster.pdf

http://msdn.microsoft.com/en-us/magazine/dn532203.aspx

http://rionscode.wordpress.com/2013/06/03/using-cors-in-asp-net-webapi-without-being-a-rocket-scientist/

https://www.simple-talk.com/dotnet/.net-framework/owin-customizing-the-web-server/

3 comments

  1. Beautiful! This saved my life. Thanks!

  2. This is a very helpful article. I am struggling with one thing. I have created a OWIN self hosted web API using windows service. Even after implementing Unity as you have described above, when I try to send a get request to my controller I get the exception stating ‘Make sure that the controller has a parameterless public constructor’. Help!

  3. Have you checked out this error? http://stackoverflow.com/questions/24254189/make-sure-that-the-controller-has-a-parameterless-public-constructor-error

    Have you registered the controllers in the Unity Container? That could be it.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: