How I use Inversion of Control containers – pulling from the container

As I expected my pre­vi­ous post prompted a few ques­tions regard­ing the Three Con­tainer Calls pat­tern I out­lined. Major one of them is how to han­dle the fol­low­ing scenario:

Container_pulling

We cre­ate our con­tainer, install all the com­po­nents in it.  Moments later we resolve the root com­po­nent, con­tainer goes and cre­ates its entire tree of depen­den­cies for us, does all the con­fig­u­ra­tion and other book­keep­ing, injects all the depen­den­cies and gives us back the new fresh ready to use objects graph that we then use to start off the application.

More often than not, this will not be enough though. At some point later in the life­cy­cle of the appli­ca­tion, a user comes in and wants some­thing from the appli­ca­tion. Lets say the user clicks a but­ton say­ing “Open a file” and at this point a “Open­File” view should be loaded along with all of its depen­den­cies and pre­sented to the user. But wait – it gets worse – Because now if a user selects a .txt file a “Dis­play­Text” view should be loaded, but when a .png file gets selected, we should load a “Dis­play­Im­age” view.

Gen­er­al­iz­ing – how to han­dle sit­u­a­tions where you need to request some depen­den­cies unavail­able at reg­is­tra­tion or root res­o­lu­tion time, poten­tially pass­ing some para­me­ters to the com­po­nent to be resolved, or some con­tex­tual infor­ma­tion affect­ing which com­po­nent will be resolved (or both).

Fac­tory alive and kicking

The way to tackle this is to use a very old design pat­terns (from the orig­i­nal GOF pat­terns book) called Abstract fac­tory and Fac­tory method.

Nit­pick­ers' cor­ners – as I know I will be called out by some purists that what I’m describ­ing here is not purely this or that pat­tern accord­ing to this or that def­i­n­i­tion  – I don’t care, so don’t bother. What’s impor­tant is the concept.

It gives us exactly what we need – pro­vides us with some com­po­nents on demand, allow­ing us to pass some inputs in, and on the same time encap­su­lat­ing and abstract­ing how the object is con­structed. The encap­su­lat­ing part means that I totally don’t need to care about how, and where the com­po­nents get cre­ated – it’s com­pletely offloaded to the con­tainer. The abstract­ing part means that I can still adhere to the Matrix Prin­ci­ple – the spoon con­tainer does not exist.

How does this work?

Using Cas­tle Wind­sor, this is very sim­ple – all you have to do is to declare the fac­tory inter­face, and Wind­sor itself will pro­vide the imple­men­ta­tion. It is very impor­tant. Your inter­face lives in your domain assem­bly, and knows noth­ing about Wind­sor. The imple­men­ta­tion is a detail, which depends on the abstrac­tion you pro­vided, not the other way around. This also means that most of the time all of the work you have to do is sim­ply declar­ing the inter­face, and leave all the heavy lift­ing to Wind­sor, which has some pretty smart defaults that it will use to fig­ure this stuff out by itself. For non-standard cases, like decid­ing which com­po­nent to load based on the exten­sion of the file pro­vided, you can eas­ily extend the way fac­tory works by using cus­tom selec­tor. With well thought out nam­ing con­ven­tion, cus­tomiz­ing Wind­sor to sup­port this sce­nario is lit­er­ally one line of mean­ing­ful code.

In addi­tion to that (although I pre­fer the interface-driven approach) Wind­sor (upcom­ing ver­sion 2.5), and some other con­tain­ers, like Aut­o­fac (which first imple­mented the con­cept), and Struc­tureMap (don’t really know about Nin­ject, per­haps some­one can clar­ify this in the com­ments) sup­port del­e­gate based fac­to­ries, where just the fact of hav­ing a depen­dency on Func<IFoo> is enough for the con­tainer to fig­ure out that it should inject for that depen­dency a del­e­gate that when invoked will call back to the con­tainer to resolve the IFoo ser­vice. The con­tainer will even imple­ment the del­e­gate for you, and it also obvi­ously means that the code you have has no idea (nor does it care) that the actual depen­dency was cre­ated by a container.

 

This is the beauty of this approach – it has all the pros and none of the cons of Ser­vice Loca­tor, and shift towards sup­port­ing it was one of the major changes in the .NET IoC back­yard in the last cou­ple of months, so if you are still using Ser­vice Loca­tor you’re doing it wrong.

  • http://igorbrejc.net/ Igor Brejc

    Krzysztof, I've been using typed fac­tory facil­ity ever since it came out and it's a very use­ful tool.

    My ques­tion is: how do you han­dle such fac­to­ries when writ­ing unit tests? Since there's no real imple­men­ta­tion, I have to mock it, which is fine but some­times it becomes annoying.

    Do you use Wind­sor con­tain­ers in unit tests too or do you man­u­ally inject dependencies?

  • http://kozmic.pl/Default.aspx Krzysztof Koźmic

    @Igor,

    Yes — I mock them just like any other class. I try to keep my unit tests small and my classes con­cise so it usu­ally is not an issue, and the fact that fac­to­ries are inter­faces means they mock with­out issues.

    If you cou­ple that with Moq's DefaultValue.Mock and Recur­sive mock­ing (see this post if you don't know these awe­some fea­tures http://www.clariusconsulting.net/…/102921.aspx )this becomes a non issue.

  • http://igorbrejc.net/ Igor Brejc

    Krzysztof, thanks for the quick response. I've read the Moq post, I'll have to check if Rhino (which I use) can do the same or sim­i­lar stuff.