Geeks With Blogs
Brian Schroer Don't Call Me Mort!

 

In my current ASP.NET MVC project, I'm focused on testability and programming to interfaces rather than concrete implementations, so I have a ton of interfaces.

I'm using the Microsoft Unity IOC Container, so my dependency injection initialization code looked like this:

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Reflection;
   4:  using Duff.Localization;
   5:  using Duff.Database;
   6:  using Microsoft.Practices.Unity;
   7:   
   8:  namespace Duff.Web
   9:  {
  10:      public static class ObjectFactoryInitializer
  11:      {
  12:          public static void Initialize()
  13:          {
  14:              RegisterTypes(ObjectFactory.UnityContainer);
  15:          }
  16:   
  17:          private static void RegisterTypes(IUnityContainer container)
  18:          {
  19:              container
  20:                  .RegisterType<IBeerRepository, BeerRepository>()
  21:                  .RegisterType<ICacheHandlerFactory, CacheHandlerFactory>()
  22:                  .RegisterType<ICompanyRepository, CompanyRepository>()
  23:                  .RegisterType<IContextState, ContextState>()
  24:                  .RegisterType<ICostCenterRepository, CostCenterRepository>()
  25:                  .RegisterType<IExceptionHandler, ExceptionHandler>()
  26:                  .RegisterType<IBreweryRepository, BreweryRepository>()
  27:                  .RegisterType<IHtmlEncoder, HtmlEncoder>()
  28:                  .RegisterType<ILogger, ErcLogger>()
  29:                  .RegisterType<ILookupHelper, LookupHelper>()
  30:                  .RegisterType<IPaginationHelper, PaginationHelper>()
  31:                  .RegisterType<IResourceStringGetter, ResourceStringGetter>()
  32:                  .RegisterType<IRetentionCodeRepository, RetentionCodeRepository>()
  33:                  .RegisterType<IRetentionScheduleLocationRepository, RetentionScheduleLocationRepository>()
  34:                  .RegisterType<IRetentionScheduleServiceFactory, RetentionScheduleServiceFactory>()
  35:                  .RegisterType<IDuffAuthorizationChecker, DuffAuthorizationChecker>()
  36:                  .RegisterType<IRmsConfiguration, WebConfig>()
  37:                  .RegisterType<IUserHelper, UserHelper>()
  38:                  .RegisterType<IUserState, UserState>()
  39:                  .RegisterType<IUserRepository, UserRepository>();
  40:          }
  41:      }
  42:  }

For all but two of the interfaces, the class names I want to resolve to are just the interface names without the "I" prefix (e.g. "IBeerRepository" to "BeerRepository"). Wouldn't it be nice if I could just tell my program to look at my assemblies, find all of the interface / class names that match like this, and automatically register them?

I knew this was possible with StructureMap, but not "out of the box" with Unity. Wouldn't it be nice if someone wrote a convention-based configuration implementation for Unity so I wouldn't have to?

Well, that someone was Derek Greer. With his Convention-based Registration Extension for Unity, I can do this:     

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Reflection;
   4:  using Duff.Localization;
   5:  using Duff.Database;
   6:  using Microsoft.Practices.Unity;
   7:  using UnityConventionExtension;
   8:  using UnityConventionExtension.Conventions;
   9:   
  10:  namespace Duff.Web
  11:  {
  12:      public static class ObjectFactoryInitializer
  13:      {
  14:          public static void Initialize()
  15:          {
  16:              RegisterTypes(ObjectFactory.UnityContainer);
  17:          }
  18:   
  19:          private static void RegisterTypes(IUnityContainer container)
  20:          {
  21:              container
  22:                  // register types where the "mapped to" class name is 
  23:                  // just the interface name without the "I" prefix:
  24:                  .AddNewExtension<ConventionExtension>()
  25:                  .Configure<IConventionExtension>()
  26:                  .Configure(x =>
  27:                  {
  28:                      x.Conventions.Add<InterfaceImplementionNameMatchConvention>();
  29:                      AddMyAssembliesForConventionBasedRegistration(x.Assemblies);
  30:                  }).Register()
  31:   
  32:                  // register other types:
  33:                  .RegisterType<IRmsConfiguration, WebConfig>()
  34:                  .RegisterType<ILogger, ErcLogger>();
  35:          }
  36:   
  37:          private static void AddMyAssembliesForConventionBasedRegistration
  38:              (ICollection<Assembly> assemblyList)
  39:          {
  40:              Assembly domainAssembly = Assembly.GetAssembly(typeof(IBeerRepository));
  41:              Assembly localizationAssembly = Assembly.GetAssembly(typeof(IResourceStringGetter));
  42:              Assembly repositoryAssembly = Assembly.GetAssembly(typeof(BeerRepository));
  43:   
  44:              assemblyList.Add(Assembly.GetExecutingAssembly());
  45:              assemblyList.Add(domainAssembly);
  46:              assemblyList.Add(repositoryAssembly);
  47:              assemblyList.Add(localizationAssembly);
  48:          }
  49:      }
  50:  }

It's actually more lines of code at the moment, but there are a lot more interfaces to come, and I won't have to write any more IOC registration code for them unless the interface/class names don't my usual convention.

(Why didn't I just use StructureMap? Maybe next project. I've used Unity before, so I'm comfortable with it. This is my first time using ASP.NET MVC, MVCContrib, Automapper and a couple of other tools that are new to me, so I don't want everything to be a learning experience.)

Thanks, Derek!

Posted on Sunday, July 4, 2010 10:59 PM | Back to top


Comments on this post: Convention-based Registration Extension for the Microsoft Unity IOC Container

No comments posted yet.
Your comment:
 (will show your gravatar)


Copyright © Brian Schroer | Powered by: GeeksWithBlogs.net