Working with Spring .NET
page 1 of 1
Published: 27 Mar 2006
Unedited - Community Contributed
Abstract
In this article, Vishal examines how to work with Spring .NET application framework with the help of examples.
by Vishal Kumar Patil
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 26974/ 35

Overview

This article demonstrates the core feature of Spring .NET that have been ported to the .NET platform as well as many of the .NET specific features that have been given the Spring .NET treatment. Spring .NET is an application framework which helps to build enterprise .NET applications. It revolutionizes the way .NET applications are configured, deployed and hosted. Spring .NET offers a lightweight Dependency Injection container built around the concept of the factories Design pattern.

Its "inversion of control" model (this is the other name of Dependency Injection) has a lot to offer if the team is struggling through issues of over-coupling and objects that are hard to unit test. Dependency Injection (DI) allows objects to be injected into a class, rather than relying on the class to create the object itself. It also provides a suite of services that can be applied to any object under Spring .NET's control. And since Spring .NET is built using standard .NET based code, applications that utilize Spring.NET have no additional dependency on COM, COM+, or Enterprise Services.

Software Requirements

.NET Framework 1.1

Spring .NET 1.1

A Spring .NET implementation

The example below demonstrates how to achieve the Dependency Injection using the Spring .NET framework. Implementation of Spring .NET consists of the following steps.

·         Defining the Interface

·         Classes implementing the Interface

·         Setting up the Config file

·         Creating the Client application to utilize the Spring .NET features

·         Defining the Interface

The code snippet in Listing 1 is a simple interface, which the objects will implement.

Listing 1

public interface IDomainObjectInterface
{
  string Name
  {
    get;
  }
}

This Interface contains one property, which returns a string representation of the name of the object.

Classes implementing the Interface

The code in Listing 2 contains two classes, ImplementationClassA and ImplementationClassB which each implement the interface. In these Implementation Classes, there is a Name property which simply returns the name of the class, depending on which concrete class is used. This Interface and implementation classes will be used to demonstrate the advantage of using the Spring .NET implementation.

Listing 2

public class ImplementationClassA:IObjectInterface
{
  public ImplementationClassA(){}
  public string Name
  {
    get
    {
      return "Implementation Class A";
    }
  }
}
 
public class ImplementationClassB:IObjectInterface
{
  public ImplementationClassB(){}
  public string Name
  {
    get
    {
      return "Implementation Class B";
    }
  }
}

Setting up the Config file

Now, add the config.xml file, which drives the Dependency Injection. Listing 3 shows the full config.xml file:

Listing 3

<?xml version="1.0"encoding="utf-8" ?>
<objectsxmlns="http://www.springframework.net">
  <objectname="DomainObjectImplementationClass" 
  singleton="false" 
  type="ImplementationClassA,SpringDIExample" />
</objects>

The configuration file consists of only two elements, <objects>, which contain all of the object definitions, and the individual <object> definitions. In the configuration file shown, there is one object definition. The object definition consists of three basic attributes which define what object is created and how it's created.

The name attribute defines the name that the Windows Application class uses when requesting an object from the config.xml file. In this case, it is "DomainObjectImplementationClass". This name is just used to reference the definitions contained in the configuration file from the client code.

Next, the singleton attribute is a Boolean flag which signifies if the object should be created as a singleton or not. Spring .NET has built-in support for making objects singletons. When this attribute is set to true, it indicates the object will be created as Singleton and when it is set to false, object will not be created as Singleton.

Finally, the type attribute defines the actual type of the object to be created. This object type will actually be loaded and returned when the config.xml file is queried. This string will be in the form of "Type, Assembly", wherein Type indicates the type of object and the Assembly indicates the Assembly Name which contains the object type. As indicated in the configuration file, the type desired is one of the types shown in Listing 2.

Creating the Client application to utilize the Spring.Net features

Here we will create a Window Application client. Add the form in the Windows Application project and add a button to the form and name the button as btnSpringNETImplementation. Paste the code (Listing 4) in the click event of the button. The code snippet demonstrates calling the Implementation classes from the config file. This adds a significant amount of flexibility and functionality to the application.

Listing 4

using System;
using System.IO;
using Spring.Objects.Factory.Xml;
using SpringDIExample;
namespace WindowsApplication1
{
  public partial class Form1: Form
  {
    public Form1()
    {
      InitializeComponent();
    }
 
 
    private voidbtnSpringNETImplementation_Click(object sender, EventArgs e)
    {
      using(Stream stream = File.OpenRead("config.xml"))
      {
        XmlObjectFactory xmlObjectFactory = newXmlObjectFactory(stream);
 
        IObjectInterface domainObjectInterface =(IObjectInterface)
          xmlObjectFactory.GetObject("DomainObjectImplementationClass");
 
        MessageBox.Show("Name is " +domainObjectInterface.Name);
      }
    }
  }
}

To use the Spring .NET Dependency injection container requires the initial setup. In the listing 4, firstly Config.xml file is opened and the object definitions are read.

Next, create the new object factory using a config.xml file as the source of your object definitions. Then call the Implementation Class with generic label for the object and upcast the object instances returned by the factory to the interface that you expect.

Finally, the last line of the MessageBox.Show remains unaffected, even though you have changed the source of the object and how it's instantiated.

Run Listing 4 and click SpringNETImplementation button in the form, which displays “Implementation Class A” message.

Now let's see the advantage of Spring .NET and the Dependency Injection: modify Config.xml file (Refer Listing 5) as shown below. The only difference lies within the type attribute.

Listing 5

<?xml version="1.0"encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net">
  <objectname="DomainObjectImplementationClass" 
  singleton="false" 
  type="ImplementationClassB,SpringDIExample" />
</objects>

Now again Run the Windows Application1 in Listing 4 and click SpringNETImplementation which displays “Implementation Class B”.

By just changing the type of the implementation class in the configuration file from "ImplementationClassA" to "ImplementationClassB", we can dynamically alter the class that is returned to the client, all without a recompile.

Editor's Note: A similar system is used throughout the ASP.NET v2 architecture, where it is commonly referred to as the "Provider Model".

Extensibility Enhancement Feature of Spring.NET

In this case, IObjectInterface is published in a public API, and would like to allow users of the API to create their own implementations of the interface, all while still utilizing several existing clients that have already been built to use the IObjectInterface. Getting the users' implementation to your clients could prove to be difficult, especially if we do not know how the class will be built or deployed. ImplementationClassC is a third implementation of the IObjectInterface, which is similar to the ImplementationClassA and ImplementationClassB classes, except this one resides in a separate assembly. Previously, both implementation classes and the interface resided in the same assembly:

Listing 6

public class ImplementationClassC:IObjectInterface
{
  public ImplementationClassC(){}
  public string Name
  {
    get
    {
      return "Implementation Class C";
    }
  }
}

Now, we will again use the above Windows Application1 to demonstrate how to call ImplementationClassC using Spring.NET framework. This requires a minor change to the original config.xml configuration file. The following is the configuration file with the necessary changes made. Again the only difference lies within the type attribute, which has been updated to point to the ImplemenationClassC type and the SimpleDIExampleExtension assembly:

Listing 7

<?xml version="1.0"encoding="utf-8" ?>
<objectsxmlns="http://www.springframework.net">
  <objectname="DomainObjectImplementationClass" 
  singleton="false" 
  type="ImplementationClassC,SpringDIExampleExtension"/>
</objects>

When we rerun the Windows Application1 and click the SpringNETImplementation button on the form, an instance of ImplementationClassC will be instantiated and returned. This is accomplished without recompiling the Windows Application, even though ImplementationClassC resides in an assembly that's physically separate from the original implementation classes.

Conclusion

In this article, we have demonstrated how to utilize Dependency Injection features with Spring .NET. The Dependency Injection pattern simplifies application code, and increases configuration flexibility by deferring component configuration and assembly to the container.

This lightweight container helps to assemble components from different projects into a cohesive application. It also saves you from writing boilerplate factory creation code over and over again. Spring .NET is an example of a framework that provides a ready to use DI container.

It's true that this pattern (and many others found throughout the .NET Framework) does not have enough advertising, and that may be the cause for their scarce usage in .NET application architectures.  Hopefully this article will help many more developers learn about this powerful technique and toolset.

Resources

Spring.NET

 



User Comments

Title: cool article   
Name: singh
Date: 2010-01-30 10:01:03 AM
Comment:
very clear and cool!
Title: .net developer   
Name: Julia
Date: 2009-05-30 12:38:00 PM
Comment:
good example, I can understand your C# implement class code,
but I stilll don't know what is
'Dependency Injection (DI) allows objects to be injected into a class, rather than relying on the class to create the object itself.'?
in what class-code that was 'injected into a class'?
appriciate if you could kindly give me an answer.
Title: Thanks   
Name: Asif
Date: 2008-06-25 5:02:27 AM
Comment:
@Mans

It's a good link. Thanks 4 that.
Title: DI   
Name: Padmanabh
Date: 2008-05-16 7:22:59 PM
Comment:
The discussion is really very simple to understand.
But is it the DI all about Spring.Net implementation?
How important are the things like Transaction Management DAO etc.?
May be these questions look silly as I have just started learning Spring Framework.
Title: Isn't this the same as pulished in the MSDN article   
Name: Mans
Date: 2006-08-17 12:36:22 PM
Comment:
There is an articel in MSDN sept '05 which shows the same exact implementation discussed here. The link to that is
http://msdn.microsoft.com/msdnmag/issues/05/09/DesignPatterns/

Also the classes need to implement 'IDomainObjectInterface
' and not 'IObjectInterface'
Title: missing   
Name: Steve
Date: 2006-07-08 4:00:43 PM
Comment:
Show all three classes in the config and then show how you can return the correct implement for each.
Title: .net   
Name: jenifer
Date: 2006-03-27 2:40:58 AM
Comment:
Excellent






Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2017 ASPAlliance.com  |  Page Processed at 2017-07-27 10:18:05 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search