ASP.NET Web API and Unity
February 26, 2012 Leave a comment
In my last post, I walked through the relatively simple task of adding Ninject to ASP.NET Web API. I’ve been looking at solving some common problems like logging and caching in an Aspect Oriented Programming approach. So I’ve been looking into Interceptors and how they can help implement AOP. More on this later. I thought I’d take a look at Unity from Microsoft’s Patterns & Practices group because it supports IoC and Interceptors. As Scott Hanselman points out, there are a lot of frameworks for this and I just chose Unity to get started.
So what does it take to swap out Ninject with Unity? Very little as it turns out. There’s a minor modification to the IDependencyResolver implementation that uses the IUnityContainer instead of IResolutionRoot. Here’s what the code originally looked like with Ninject:
public class NinjectDependencyResolver : System.Web.Http.Services.IDependencyResolver { private readonly IResolutionRoot resolutionRoot; public NinjectDependencyResolver(IResolutionRoot kernel) { resolutionRoot = kernel; } public object GetService(Type serviceType) { var service = resolutionRoot.TryGet(serviceType); return service; } public IEnumerable<object> GetServices(Type serviceType) { var services = resolutionRoot.GetAll(serviceType); return services; } }And here’s what it looks like using Unity:
public class UnityDependencyResolver : System.Web.Http.Services.IDependencyResolver { private readonly IUnityContainer container; public UnityDependencyResolver(IUnityContainer container) { this.container = container; } public object GetService(Type serviceType) { object service = null; if (!container.IsRegistered(serviceType)) { if (serviceType.IsAbstract || serviceType.IsInterface) { return service; } } service = container.Resolve(serviceType); return service; } public IEnumerable<object> GetServices(Type serviceType) { IEnumerable<object> services = container.ResolveAll(serviceType); return services; } }After that, I made a minor modification to RegisterDependencies. Really, it’s pretty much just a syntax change from Ninject’s Bind to Unity’s RegisterType. Here’s what the code originally looked like with Ninject:
public class WebApiApplication : System.Web.HttpApplication { public static void RegisterDependencies() { IKernel kernel = new StandardKernel(); kernel.Bind<ISomeService>().To<SomeService>(); var ninjectResolver = new NinjectDependencyResolver(kernel); GlobalConfiguration.Configuration.ServiceResolver.SetResolver(ninjectResolver); } protected void Application_Start() { RegisterDependencies(); AreaRegistration.RegisterAllAreas(); RegisterRoutes(RouteTable.Routes); RegisterGlobalFilters(GlobalFilters.Filters); BundleTable.Bundles.RegisterTemplateBundles(); } }And here’s what it looks like using Unity:
public class WebApiApplication : System.Web.HttpApplication { public static void RegisterDependencies() { IUnityContainer container = new UnityContainer(); container.RegisterType<ISomeService, SomeService>(); var unityResolver = new UnityDependencyResolver(container); GlobalConfiguration.Configuration.ServiceResolver.SetResolver(unityResolver); } protected void Application_Start() { RegisterDependencies(); AreaRegistration.RegisterAllAreas(); RegisterRoutes(RouteTable.Routes); RegisterGlobalFilters(GlobalFilters.Filters); BundleTable.Bundles.RegisterTemplateBundles(); } }I was really happy with how easy it was to swap out IoC frameworks. Even more reason why you should just pick one and get started. There's no excuse to not use IoC to elegantly resolve dependencies.