I was perusing the session list for ALT.NET Canada this morning (sorry I couldn’t make it guys) and saw this session title that reflects something I’ve had quite a few conversations about this year.
Building extensible frameworks leveraging framework consumer selectable IoC containers.
As long as we’re going to work in static typed languages, it’s a major advantage to achieve extensibility and pluggability by utilizing an existing Inversion of Control container. I’ll make the statement that starting with an existing IoC tool makes framework construction far simpler and cheaper than it was before. The problem with that is that there are multiple IoC containers out there, and tying your framework to any of those containers is bound to irritate a big swath of people.
When we were deciding between Ruby on Rails, the ASP.Net MVC, and MonoRail for our project architecture in June, I dismissed MonoRail in small part because I didn’t want to be forced to use Windsor as our IoC tool (for some reason). We’re perfectly content with the MVC framework at the moment*, but after reading through the MVC code and the way that they pass around dependencies through the myriad SomethingContext objects, I think the MVC team could streamline their own code quite a bit by using an IoC tool to resolve dependencies. Now, that brings up a contentious issue, which container would they use? The answer is that they can’t use any specific container.
When I was building the initial code that has became Fluent NHibernate there were a couple places where I needed to use an IoC container to resolve NHibernate objects and deal with configuration. I obviously chose StructureMap and buried a couple hard references to ObjectFactory.GetInstance<T>() in the code. The coupling to StructureMap doesn’t particularly concern me, but when the code first went public, Nate Kohari (author of Ninject) lamented on Twitter that the tool was coupled to StructureMap.
So, to make it safe for both Nate and myself to use the IoC of our choice, what I’d really like to see is a common interface to represent the very baseline functionality of an IoC container so that we could build and release frameworks that utilize an IoC container without forcing a particular choice of tool onto the development teams. A couple people are already going down the path of abstracting an IoC container with one off solutions. Off the top of my head I can think of at least three:
- Whatever boring name that Prism is now called (and I owe P&P a reference implementation of Prism with StructureMap. I’m getting there)
All of these frameworks have a more or less similar interface for the container, then an adapter for most of the major IoC tools. I’d like to propose, and I’m not the first, that a new Service Locator abstraction be added to the .Net Framework itself as a first class citizen and publicized a little bit so framework builders can take advantage of a common interface. I’d like to start a new petition to make this little, itty bitty work be a part of the MEF project within Microsoft. All I think it needs to do is provide an interface with:
and leave the registration completely alone because it’s so radically different from one tool to another. Then, give us something like Thread.CurrentPrincipal for a wellknown place to put the container.
*Honestly, we’ve replaced a fair amount of the MVC framework with our own stuff, but that’s a post for another day. The best thing about the MVC is that it’s so small and fairly modular, so it’s relatively easy to swap in your own “special sauce” to embed conventions and more opinionated structures.