Click here to Skip to main content
Click here to Skip to main content

Dependency Injection using Spring.NET

By , 28 May 2008
 

Introduction

Spring.NET is one of the popular open source frameworks ported from Java platform. It offers a lot of functionality, and in this article, I will discuss about Dependency Injection and how it is supported in Spring.NET.

Dependency Injection

Dependency Injection is a technique that decouples the consumer from the actual implementation during design/compile time and binds them at run time.

At a lower level of implementation, in a typical application, there will be a class that implements a logic, and it will be consumed by another class. The reason why we have two classes will drag us to discussions like modularization of code, reusability, maintainability etc.

When we consume a class instance (let's say, ClassB) from another class instance (ClassA) at compile time, then any changes to ClassB will affect ClassA. For every change, we need to recompile, redeploy the whole stuff, and other related issues. In this case, there is a static or compile time binding between ClassA and ClassB.

Dependency Injection is one of the techniques that relieves us from the pain of static binding and decouples ClassA and ClassB. The end result, a decoupled or loosely coupled system.

There are lot of materials available to understand DI in detail. Martin Flower has an excellent article that explains the concepts, with examples.

DI using Spring.NET

Spring.NET offers DI as an out of the box solution. In this article, I will dig deep and explain how we can leverage the benefits offered by Spring.NET.

Scenario

I created an application that has the typical three layers - Presentation, Business Logic Layer (BLL), Data Access Layer (DAL). The UI layer implements the MVP pattern, in which I created views (WinForms), Presenter classes, and DataTable as Models.

The UI calls the Presenter, which interacts with BLL; BLL interacts with DAL and retrieves data from the Northwind database.

The following diagram shows the layers of the application:

LogicalArchitecture.JPG

Limitations of a tightly coupled system

In a tightly coupled system, the UI is dependant on BLL, and the BLL is dependant on the DAL. If we change something in the DAL, then all the layers need to be recompiled and redeployed.

Advantages of a loosely coupled system

Instead, if we develop in a loosely coupled manner, then the compile time dependency can be avoided. The instances can be chained at runtime. This gives the following advantages:

  • Decouples the layers
  • Ability to link the layers at runtime
  • Ability to link a different implementation at runtime for QA/testing purposes
  • Ability to develop the layers independently, and integrate at a later point

Steps to implement DI using Spring.NET

Having discussed about the advantages, it's now time to see how we can go about implementing the technique. Following are the broad steps that need to be followed to implement DI using Spring.NET.

Step 1

Define your interfaces that will be exposed by the layers.

Step 2

Provide concrete implementation for the interfaces defined by your layer.

Step 3

Configure the objects in the Spring.NET configuration.

Step 4

Initialize the Spring.NET configuration at runtime using the Spring.NET API.

Step 5

Use the Spring factory to create the instance for you.

Step 6

Consume the instance created by the Spring factory in the calling layer.

Implementation at ground level

Having seen the steps at 10,000 feet, it's now time to see how things are implemented at ground level.

I have created a layered application with three projects. Each layer defines the interface and the implementation.

SolutionStructure.JPG

Defining the interface

The Data Access Layer defines the interface, which the BLL will refer to. This interface defines methods that will retrieve data from a table.

public interface IDAL
{
    DataTable GetAll();
    DataTable GetById(string ID);
}

Provide concrete implementation

The GetAll() and GetById() methods are shown as below:

public class CustomerDAL : IDAL 
{
    // Implementation for GetAll()
    public DataTable GetAll()
    {
        // Create connection
        // Create command
        // Retrieve all records and return as DataTable
    }

    // Implementation for GetById()
    public DataTable GetById(string ID)
    {
        // Create connection
        // Create command with filter criteria
        // Retrieve matched records and return as DataTable
    }
}

Spring object configuration

So far so good. Now, it's time for us to understand the Spring configuration. First, you declare the Spring configuration section, then define the object/object node with type and assembly information. The object node's name attribute must be unique, and it uniquely identifies the object. The type specifies the full type of the object. The singleton attribute specifies whether to create a single instance and serve for multiple requests (singleton implementation), or a new instance always.

The following snapshot gives the configuration of the application:

Configuration.JPG

Initialize Spring configuration

Add a reference to the Spring.Core assembly. Include a reference to the Spring.Context and Spring.Context.Support namespaces.

Initialize the configuration using the ContextRegistry.GetContext() method. This will validate the configuration, check for the existence of objects, and return an IApplicationContext instance.

Get the instance using Spring

Use the IApplicationContext instance returned by the ContextRegistry.GetContext() method to get the instance.

    // Include namespaces
    using Spring.Context;
    using Spring.Context.Support;

    // Get the context
    IApplicationContext applicationContext = ContextRegistry.GetContext();

    // Get the instance through Spring configuration
    IBLL _customerBLL = applicationContext[“customerBLL”];

    // Work with the instance
    _customerBLL.GetAll();

Work with the instance

Once the object is instantiated, you can go ahead and perform the operations that you wish to. In our case, Customer DAL's GetAll() method is called from the Customer BLL instance.

Practical usage

After working through Spring.NET DI, one obvious question is how it can be helpful in a real time scenario. Following are some of cases where DI can be used in a real time basis:

  • The dependant layer can be changed at runtime based on the environment. For example: one can provide a test implementation for the test/QA environment and the actual implementation for the production environment
  • The incremental bug fixes can be done offline and linked at integration/testing phase
  • Parallel development of layers by different teams and can be linked at integration phase

About the sample application

The sample application has two forms - Customer and Employee. Both retrieve all data or data based on an ID. They follow a similar pattern.

When the form gets loaded, the presenters are initialized using Spring.NET's DI technique to the appropriate presenter. The Customer form gets linked to CustomerPresenter; similarly, the Employee form gets linked to the EmployeePresenter instance. The presenter gets linked to the appropriate BLL layer. The BLL layer gets linked to the appropriate DAL instance.

All these happen using Spring.NET's DI technique.

Conclusion

Dependency Injection is a key technique which helps in building loosely coupled systems. Spring.NET offers it as an out of the box solution, and it is the base principle for the rest of the components within Spring.NET.

Happy reading! Happy coding!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Niranjan Kumar
Architect Cognizant Technology Solutions
United States United States
Member
Solution Architect working for Cognizant Technology Solutions.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionGreat ArticlememberMember 1000385821 Apr '13 - 23:28 
Thanks, That was well explained and it really helped me to understand DI using Spring.NET
GeneralMy vote of 5memberreachen24 Mar '13 - 21:46 
it's easy to learn spring.net by follow this articel.
PS:the dll(antlr.runtime.dll) seemed doesn't work...
QuestionHow is DI different from the class factory pattern?memberWang Chun Hsun22 Aug '12 - 22:54 
I can achieve the same thing with a class factory and .NET reflection.
Suggestion[My vote of 2] Difficult to use your source codememberWang Chun Hsun22 Aug '12 - 22:52 
I think you could do a better job by including the referenced Spring.NET DLL's and the database file. You could also remove reference to the Antlr.Runtime.dll, which at a quick glance of your source code, is not required.
GeneralNice articel for learning spring.net!memberwsc09188 Aug '12 - 19:38 
Nice articel for learning spring.net!
QuestionHow to pass a Constructor Parameter using Spring.Net ????memberMember 887517425 Jun '12 - 23:44 
How to pass a Constructor Parameter using Spring.Net ????
Abhi

QuestionSpring container accessed at levels where it should not be necessarymemberMember 202489428 Mar '12 - 4:53 
I agree with the comment above that says you're not using the full power of spring.net.
 
I think there are issues creating form objects using the spring.container (I don't work with winforms much), so I guess the forms dependencies have to be set by accessing the container. But the dependencies' dependencies surely can be wired by Spring?
 
customerBLL = (IBLL) WinClient.ApplicationContext["CustomerBLL"];
 
should be replaced by a property of type CustomerBLL, or better still of type ICustomerBLL.
 
It is not good practice to have a dependency on spring.net embedded into every class.
GeneralMy vote of 5memberwindmateus2 Jan '12 - 10:50 
Excellent article, very useful to me.
GeneralTransactionmemberpurusingh4 Aug '10 - 5:38 
You haven't mentioned about transaction.
How do you handel transaction here?
GeneralI think it is not using power of springmemberpurusingh4 Aug '10 - 5:37 
I haven't done Spring.Net but I have done some in Java.
Since we can do DI in spring there is no need to hard code in Business logic.
We can assign it in config file.
 

I think these lines can be removed.
 

public EmployeeBLL()
: base()
{
_employeeDAL = (IDAL)_applicationContext["EmployeeDAL"];
}
GeneralMy vote of 5memberyaya rabiu david7 Jul '10 - 22:35 
straight to the point
GeneralSimple and straightmemberyaya rabiu david5 Jul '10 - 23:56 
This is simple and straight to the point. Thanks
Questionwhere the Spring configuration file?memberjuliji99930 May '09 - 17:09 
1, when you talk about 'Spring configuration' and
'The following snapshot gives the configuration of the application'
* you didn't say that's a xml file, when we [download source code]
*we didn't find that file neither, so we even don't know what's that
*file name, even there is a file1.xml name, how project know this file?
there may be file2.xml, file3.xml files. Is it a confilg.xml?
*from your BLL, DAL, WinClient all folder didn't see this file neither.
*even in your web site that's just a photo copy, not writing code like IDAL! *so the project can work without that xml file?
2,
when I got customerID, why I need use BLL to call customerBLL.GetById(ID) first, then from BLL to call DAL _customerDAL.GetById(ID)?
Why I can't from customer to call DAL _customerDAL.GetById(ID) directly,
but need the BLL call in between the customer and DAL ?
AnswerRe: where the Spring configuration file?memberDiago Velit5 Jul '09 - 15:05 
Look for the App.config file.
QuestionAre interfaces really stable?protectorMarc Clifton17 Apr '09 - 14:53 
The problem with this approach, IMO, is that interfaces are not necessarily stable--if the BLL or DAL add functionality, then the interface needs to be changed, and the entire application has to be rebuilt anyways, because the application and the modules share the interface definition, if I understand this correctly. And certainly, during development interfaces change a lot, so that seems to be a weakness in this architecture.
 
Marc
 

GeneralPlz Can Give Example to Exception Handling in Spring.NetmemberRoseonDotNet6 Nov '08 - 1:56 
Hi Niranjan
 
i am new to spring.Net
 
can u give Refrence for Logging and Exception in Spring.Net
 
Thx
 
SRIDHAR.P

GeneralThanks for the wonderful workmemberChintan.Desai21 Oct '08 - 23:46 
.
 
Thanks,
Chintan(India)

GeneralGreat Article!memberFakher Halim20 Jul '08 - 14:34 
I find it very useful! You tried to express every thing in such an elegant way -- congratulation.
I am giving you 5 out of 5 marks! Smile | :)
 
Fakher Halim

GeneralStop double submittingmvpJohn Simmons / outlaw programmer28 May '08 - 11:16 
Subject says it all.
 

"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997
-----
"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001

GeneralRe: Stop double submittingmemberNiranjan Kumar29 May '08 - 5:38 
Hi John,
 
Thanks for your comment.
 
I am sure the same topic will be discussed in codeproject or any other site. What I have here is a different perspective of the same topic and usage in a layered architecture. I strongly feel that this will be helpful to developers who want to learn Spring, logical layering, decoupling them.
 
Thanks
Niranjan
 
Niranjan Kumar
Architect, Cognizant Technology Solutions. USA.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 28 May 2008
Article Copyright 2008 by Niranjan Kumar
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid