(In case you don’t know what IoC containers are, I advise you to take a peek at Part 4 of this series first before continuing with this article.In case you are not familiar with Microsoft Unity IoC framework which I would be using in this post read part 7)

Intro

Before I start, I would like to recommend you to subscribe to Alt.NET mail list where you have daily top notch discussions about various ultra interesting subjects. One of April subjects was Are Opaque Depencies Bad? (Mockist TDD’s effect on design) where you can see that some of very smart people were stating that Opaque dependencies are sometime acceptable compromise because they encapsulate complexity and the component dependency information we get anyhow are not that valuable.

IMHO that is wrong because of the reasons I would state in this post and which can be summarized as:

In first line of my the NumberOfUsersActiveInLast10Days method, an instance of type implementing IUserProvider has been retrieved and then used it in next line to get list of all users. Once the list of users would be retrieved from DAL provider class, method code iterates and filters out all of the users which name starts with given string and which were active in last 10 days.

As you can see the usage of service locator is “hidden” into the method code and invincible outside of that method.

we wouldn’t get any clue that UserManager has any dependency on ServiceLocator and UserManagerProvider.

This style of implicit usage of IoC framework where IoC framework is embed directly into the members using it, is called opaque dependency injection.

According to my personal experience opaque style is something looking very appealing to people new to IoC because it is a way of implementing IoC with “nothing changed”, so usually it is considered as “acceptable compromise” 🙂

Testing the opaque dependencies

Let see why I found this opaque style bad on example of how making test for this NumberOfUsersActiveInLast10Days method would look.

The test I would write would have to verify that for no users in database which have username starting the with given string, program would return zero.

I am sitting in black box testing camp (no testing of private method and looking at the code being tested maximally discouraged) so I usually start my tests writing the playback code

If we look at the NumberOfUsersActiveInLast10Days method we would see that ServiceLocator class is not been used nay more there. Method now uses userProvider field without knowing how the _userProvider field is been initialized.

We have also two constructors:

Internal constructor accepting the parameter of IUserProvider data type and store its value into the _userProvider field

Public default constructor not accepting any parameters but which uses the ServiceLocator to retrieve from IoC container service implementing the IUserProvider interface and then calling internal constructor passing that service to internal constructor parameter

“Dude, this is no transparent dependency…”

Usually examples I was finding on net wouldn’t look like the just given example. The internal constructor would become public and the current default constructor doing poor man dependency injection through ServiceLocator wouldn’t exist at all.

Their rationale is that the UserManager would always be constructed using IoC framework which would automatically perform the injection during the IoC container construction time.

In real enterprise development that is often not true because we could have in existing code base a lot of places doing already doing UserManager mgr=new UserManager() (constructing without the usage of IoC)so that implicit IoC dependency injection wouldn’t work for them.I guess also that updating all of the current code just to be able to serve the IoC framework wouldn’t be probably very high on “resource allocation list“ spreadsheet, so we could count on the fact that this “legacy” code would stay like it is now.

What I am doing in my approach is basically switching that implicit IoC dependency injection with explicit one. The major difference here is that I am basing my IoC class design on default constructor and not on some specialized one. That’s why when code construct the class, in both cases (using IoC or new keyword) the result is the same – automatic service resolution and dependency injection. In other words, all this would work with any legacy code using the UserManager class.

Another significant gain (IMHO) from my approach is that I am hiding the complexity from production code (only default constructor exposed) while still having the same IoC concepts in place.

After all, having class design “open for testing but closed for code noise” is the whole point of this DTF blog post series.

“Dude, this is transparent dependency, just it is V2” 🙂

Testing the transparent dependencies

Once we have our code restructured testing is much more easier and even possible without using the ServiceLocator at all.

Writing the test in this case would show me during the Playback definition that UserManager class have a constructor accepting the IUserProvider class which would lead me to the conclusion what I need to mock in order to have this test done without “run until not complaining” approach I described in opaque test example above.

So first we would add to AssemblyInfo.cs file of UserManager appropriate assembly attribute

[assembly: InternalsVisibleTo(&quot;UserManager.Test&quot;)]

After this User.Test assembly would get access to UserManager internal constructor above so the test would look like this

I am using internal UserManager constructor to inject UserProvider mock.

While writing the line using the internal constructor I realized (from constructor signature) that I need mocked instance of IUserProvider (first line of the test method)

Conclusion

IMHO, using of transparent dependency significantly simplifies the test making. The approach here I presented (with internal constructor) is variation of standard implementation made to hide the complexity and remove the rope from the hands of TDD unskilled developers. Applying it could enable having a small “TDD core team” of people doing component level design and enabling IoC (with all of the benefits) and all other developers totally unaware of the IoC class design which should reduce training costs and increase IoC adoption chances in organizations not applying it.

What’s next?

My next blog post would be on how AutoMockingContainer (AMC) makes testing easier in cases we are using transparent dependency injection style so in a sense with this blog post makes complete explanation on how to test IoC based components done with transparent dependency injection style

Source code of the examples (opaque and transparent) presented in this post can be found here

What I still don’t get is the following:
Suppose I am going to use the UserManager class from your 2nd example (the one having 2 ctors) in my project. Since you’ve made the 2nd ctor internal I cannot see it and this forces me to use the parameterless ctor. By doing so I get the exact problems you mentioned in your opaque sample. So how is this transparent for me? And what will happen if you make the 2nd ctor public and I pass null? What will happen if your UserManager requires another dependency in the near future? That will break my code because all this DI stuff is not based on contracts which IMHO is one of the most fundamental problems for using it in the first place.

Nikola, great series, thanks. When using IoC, there is a "soft" dependency instead of a "hard" dependency between projects. How do you manage your project references in those cases?
Take these projects for instance: UI, BSL, IDAL, SqlDAL, OracleDAL
The BSL would need a hard dependency on IDAL to compile but nothing else. At runtime, the UI project would need the SqlDAL or OracleDAL assemblies in the bin depending on which one was used.
How do you manage these references? Post build events?
Thanks.

Troy,
In short:
BSL should have only dependency on IDAL and during the runtime appropriate IDAL service contract implementation should be injected.
Typically, you have two solutions to do that:
a) Configuration based solution
You would define in some .config file list of the types (services) implementing the IDAL interface (service contract) and assign each one of them some key. Then during the run time you would determine which key value you need and then the IoC container would (using a reflection) create you instance of the desired service.
Upside of this approach: no need to reference anywhere concrete services.
Downside: the fact you have to use config file.
b) Builder based solution
You create separate Builder dll which reference assemblies containing IDAL, SqlDAL and OracleDAL. Then you create Bootstrap class with Init method doing something like
If (someCondition)
ServiceLocator.Register<IDAL, SqlDAL>()
Else
ServiceLocator.Register<IDAL, OracleDAL>()
Then in your main assembly you reference the assembly containing the IDAL interface and whenever needed you just do ServiceLocator.Retrieve<IDAL>()
This sounds like a nice example for Separate interface blog post so if this summary info won’t be enough for you stay tuned for that blog post where you would have code example and detail explanation
HTH,
Nikola