Kurt Claeys

DEVITECT.NET

  Home  |   Contact  |   Syndication    |   Login
  126 Posts | 43 Stories | 163 Comments | 13 Trackbacks

News

I'm a .NET architect / developer from Belgium and also trainer in .NET topics.

Kurt CLAEYS

 



view my trainer profile on TrainerExchange.com
 

Join Me at Tech·Ed EMEA Connect for Developers!

View Kurt CLAEYS's profile on LinkedIn


Being ...





 


Working ...


and



Reading ...



Riding ...

Tag Cloud


Article Categories

Archives

Post Categories

Links

 

As my interest grows to learn more about the J2EE development platform (I strongly believe that knowledge of both platforms is needed to work in an IT architect role) I started looking at Spring.Net. Spring is the most widely used application framework in the Java world. Spring is somehow comparable to what the Microsoft Enterprise Library is offering. (Hmm, not exactly ...)

Spring (and also Spring.net) supports the Inversion of Control (IoC) principle in a really easy and efficient way. Not as complex as ObjectBuilder in Enterprise Library.

I came up with a little tutorial on Loose Coupling and Dependency Injection with Spring.NET. Design patterns like these are hard to understand without a good example. In this post I will guide you in this area by coding a simple scenario.

Let's consider a program which instantiates an object of ClassA (could be a windows form). That object needs a reference to another object that performs some logic (could be a domain object or a proxy to a WCF service). Let's call this ClassB.  ClassA has a property which refers to ClassB. When the progam asks ClassA to do something, ClassA will call a method on ClassB.

Loose Coupling ? Loose Coupling comes in very handy for testing purposes : to test the behavior of ClassA we want to change ClassB to another Class (let's call it ClassB2) which has the same method but doesn't execute the logic to really call to a database backend but returns some hardcoded values. In a unit test we could assert the outcoming of the method in ClassA based on those harcoded values.

 

I will give you three different approaches for this scenario : 

 

1. Not Loose coupled example, no dependency injection, no spring.net

class ClassA { public ClassB refToB { get; set; } public void DoSomething() { string answerFromDatabase; answerFromDatabase = refToB.GetSomehingFromADatabase(); Console.WriteLine(answerFromDatabase); } }

There's is no way to use another version of ClassB (ClassB2) without changing ClassA and recompiling it.  ClassA is really dependent on ClassB.

So this code snippet will not compile.

a = new ClassA(); a.refToB = new ClassB(); a.DoSomething(); a.refToB = new ClassB2(); //<- does not compile of course. a.DoSomething();

A solution for this is working with interfaces.

 

2. Loose Coupled with an Interface, no dependency injection, no spring.net

An Interface called IClassB is added.

 

public interface IClassB { String GetSomethingFromADatabase(); }

 

Now both ClassB and ClassB2 implement this interface. This interface holds the definition of the methods that ClassB (and ClassB2) should implement. ClassA now has a property which type is this Interface.

 

class ClassA { public IClassB refToB { get; set; } public void DoSomething() { string answerFromDatabase; answerFromDatabase = refToB.GetSomethingFromADatabase(); Console.WriteLine(answerFromDatabase); } }

 

This allows the calling code to decide which version of ClassB is given to ClassA. Both code snippets below are correct.

a = new ClassA(); a.refToB = new ClassB(); a.DoSomething(); a.refToB = new ClassB2(); a.DoSomething();

OK, more or less loose coupled, ... but again we need to recompile the application to switch from the real ClassB to the hardcoded ClassB2.

 

3. With Dependeny Injection using Spring.NET

Instead of using a property we add a constructor to ClassA which takes a reference to the interface IClassB as paramater. This construcor will hold this reference in a private field inside the class.  The type of this private field is also the interface.

class ClassA { private IClassB refToB; public ClassA(IClassB b) { refToB = b; } public void DoSomething() { string answerFromDatabase; answerFromDatabase = refToB.GetSomethingFromADatabase(); Console.WriteLine(answerFromDatabase); } }

By using the IoC container of Spring.NET the choice of which version of the class (ClassB or ClassB2) to be used by ClassA is defined in the app.config file and the instantiation of ClassA is done by calling the static method GetObject() on the Spring context with a string as parameter that refers to the needed object (ClassB or ClassB2) in the spring section of the configuration. 

 

 

a = (ClassA)ContextRegistry.GetContext().GetObject("MyClassA"); a.DoSomething();

Notice that the new statement is not used anymore, which is typicall when using the Inversion of Control pattern.

The dependencies between ClassA and an implementation of ClassB is defined in the spring section of the app.config file.

<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <sectionGroup name="spring"> <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core"/> <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" /> </sectionGroup> </configSections> <spring> <context> <resource uri="config://spring/objects"/> </context> <objects xmlns="http://www.springframework.net" > <object id="MyClassA" type="SimpleSpringDemo.WithDI.ClassA, SimpleSpringDemo" singleton="true"> <constructor-arg index="0" ref="MyClassB"/> </object> <object id="MyClassB" type="SimpleSpringDemo.WithDI.ClassB, SimpleSpringDemo" singleton="true"> </object> </objects> </spring> </configuration>

In this configuration the object with id MyClassA will be instatiated as singleton (as defined by setting the singleton attribute to "true") and Spring injects the object refered by MyClassB into the constructor.  MyClassB refers to the type (defined by a namespace, classname an assemblyname) of the actual object the IOC container will instantiate and give to ClassA as the parameter in the constructor.

So without recompiling, by just changing the configuration, we can decide wich object classA will use to perform it's tasks : the real object talking to the backend or a harcoded mock object.

Great !!

posted on Thursday, February 14, 2008 10:20 AM

Feedback

# re: Dependency Injection and IoC with Spring.NET 2/15/2008 9:37 AM t
What is the diff between IoC and the Provider Pattern?

# re: Dependency Injection and IoC with Spring.NET 1/15/2009 6:53 PM Beryl Wilson
Very nice article.

# re: Dependency Injection and IoC with Spring.NET 3/7/2009 3:28 PM Martin
Very nice article, I like to know how Spring use AOP, and what is the diferent between AOP and Enterprise Library concept.

Thanks.

# re: Dependency Injection and IoC with Spring.NET 4/25/2009 1:21 PM Gluix
Thanks for this excelent article, very helpful.

# re: Dependency Injection and IoC with Spring.NET 5/20/2009 8:33 AM mr_fuku
sweet article dude - thanks for the explanation...very well written and concise.

Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification: