4. Dependency Injection
Dependency injection can be considered a consequence of inversion of control. We will illustrate this with a new example. Consider the following 3-tier web application:
![]() |
We will assume that access to the DAO layer is controlled by the [IArticlesDao] interface discussed earlier and that the entire application is a web-based shopping application. The items are those managed by the [Dao] layer. We assume that access to the business layer is controlled by the following interface:
Public Interface IArticlesDomain
' buy a shopping cart of items
Sub buy(ByVal basket As Basket)
' Get the list of items
Function getAllArticles() As IList
' Get a specific item
Function getArticleById(ByVal idArticle As Integer) As Article
' to record errors
ReadOnly Property errors() As ArrayList
End Interface
We won't dwell on the meaning of the various methods. We will simply note that the [getAllArticles] method, which is supposed to retrieve the list of all items for sale, needs access to the data. To obtain it, it must call the [IArticlesDao] interface. The skeleton of a class implementing the [IArticlesDomain] interface might look like this:
Imports istia.st.articles.dao
...
Namespace istia.st.articles.domain
Public Class PurchaseItems
Implements IArticlesDomain
'private fields
Private _articlesDao As IArticlesDao
Private _errors As ArrayList
' constructor
Public Sub New(ByVal articlesDao As IArticlesDao)
_articlesDao = articlesDao
End Sub
...
End Class
End Namespace
As we mentioned, certain methods of the business layer interface need to request data from the [Dao] layer. Our [AchatsArticles] implementation class of the [IArticlesDomain] interface therefore needs a reference to an implementation of the [IArticlesDao] interface. Above, the private field [_articlesDao] serves as this reference. This reference is provided when an [AchatsArticles] object is constructed.
Suppose the [ItemPurchases] class has been written and we want to test it with a [Nunit] test. Let’s build this test so that it uses a Spring configuration file:
...
Imports Spring.Objects.Factory.Xml
Imports System.IO
...
<TestFixture()> _
Public Class NunitSpringTestArticlesDomain
' the object under test
Private articlesDomain As IArticlesDomain
<SetUp()> _
Public Sub init()
' Get an instance of the Spring object factory
Dim factory As XmlObjectFactory = New XmlObjectFactory(New FileStream("spring-config-domain.xml", FileMode.Open))
' Request instantiation of the Articles DAO object
articlesDomain = CType(factory.GetObject("articlesdomain"), IArticlesDao)
End Sub
...
End Class
What would be the content of Spring's configuration file [spring-config-domain.xml]? It could be as follows:
<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE objects PUBLIC "-//SPRING//DTD OBJECT//EN"
"http://www.springframework.net/dtd/spring-objects.dtd">
<objects>
<description>Management of an articles table</description>
<!-- the implementation class for the IArticlesDao interface -->
<object id="articlesdao" type="istia.st.articles.dao.ArticlesDaoPlainODBC, articlesdao">
<constructor-arg index="0">
<value>odbc-firebird-articles</value>
</constructor-arg>
<constructor-arg index="1">
<value>SYSDBA</value>
</constructor-arg>
<constructor-arg index="2">
<value>masterkey</value>
</constructor-arg>
</object>
<!-- the implementation class of the IArticlesDomain interface -->
<object id="articlesdomain" type="istia.st.articles.domain.AchatsArticles, articlesdomain">
<constructor-arg index="0">
<ref object="articlesdao" />
</constructor-arg>
</object>
</objects>
This file is the one already used to instantiate the [IArticlesDao] singleton from the [Dao] layer, to which we have added the code to instantiate the [IArticlesDomain] singleton from the business layer. How will this be constructed?
- External code requests a reference to the singleton named "articlesdomain" from Spring in the configuration file. This is the case with the [init] method of our test class:
<SetUp()> _
Public Sub init()
' We retrieve an instance of the Spring object factory
Dim factory As XmlObjectFactory = New XmlObjectFactory(New FileStream("spring-config-domain.xml", FileMode.Open))
' we request the instantiation of the articles DAO object
articlesDomain = CType(factory.GetObject("articlesdomain"), IArticlesDao)
End Sub
- Spring finds the definition of the singleton in question in its configuration file. It discovers that to instantiate it, it needs another singleton called "articlesdao":
<object name="articlesdomain" class="istia.st.articles.domain.AchatsArticles, articlesdomain">
<constructor-arg index="0">
<ref object="articlesdao" />
</constructor-arg>
</object>
- Spring will then instantiate the "articlesdao" singleton. We have already explained how it does this.
- Once this is done, it can instantiate the "articlesdomain" singleton and return a reference to it to the code that requested it.
This mechanism could be diagrammed as follows:
![]() |
We can see that Spring has managed the dependency that the "articlesdomain" singleton had on the "articlesdao" singleton. To use Spring in this way, we had to build a class with a constructor that accepts the dependent singleton as an argument:
Imports istia.st.articles.dao
...
Namespace istia.st.articles.domain
Public Class ArticlePurchases
Implements IArticlesDomain
'private fields
Private _articlesDao As IArticlesDao
' constructor
Public Sub New(ByVal articlesDao As IArticlesDao)
_articlesDao = articlesDao
End Sub
...
End Class
End Namespace
The term "dependency injection" encompasses both:
- the specific way of constructing the classes to be instantiated based on their dependencies
- the way Spring manages these dependencies when instantiating these classes

