Spring .NET6 is an application framework which provides lots of functionalities to simplify the building of enterprise applications. The functionalities are divided into independent modules. An exception is the Core module which represents the fundament of this framework. Most of the other modules require the Core to work properly. The modular architecture allows to chose just the necessary modules for own applications. Figure 8 shows an overview of the various modules shipped with Spring .NET 1.1 RC1.
Figure 8: Overview of the modules in Spring .NET [Spring07].
Spring .NET supports the development of web applications and server components but it lacks of assistance for Windows-based applications. Therefore, only the Core block of the Spring .NET modules is taken into consideration for this thesis. Although, other blocks (e.g. ORM) can be useful too for the development of a Test Suite but they are not in the scope of the requirements defined in chapter 2.
Spring .NET contains a flexible IoC Container for the wiring of collaborating components. It supports constructor injection, setter injection and it is possible to call a static factory method instead of a constructor. The preferred way of configuring the managed objects and their dependencies is by an XML file. However, the framework is flexible enough to be extended by other configuration mechanisms.
Typically, the components are described in an XML file (Listing 5). The XML
attribute ref
can be used to declare the dependent components (Line 4). The
identification of the components is done via string values. Besides injecting
dependent components, Spring .NET is as well able to inject intrinsic values
(Line 9) and arrays. Moreover, it can modify collections which are exposed by
properties.
1 <objects>
2 <object id="MyMovieLister" type="MovieLister.MovieLister,
3 MovieLister">
4 <property name="MovieFinder" ref="MyMovieFinder" />
5 </object>
6
7 <object id="MyMovieFinder" type="MovieFinder.MovieFinder,
8 TextFileMovieFinder">
9 <constructor-arg index="0" value="Movies.txt"/>
10 </object>
11 </objects>
Listing 5: Extract of a Spring .NET configuration file.
Listing 5 shows a small example for a Spring .NET configuration. It uses the
MovieLister
example from Fowler’s article about Dependency Injection
(Fowler04a). The configuration defines a MovieLister
component that requires a
MovieFinder
component in order to work (Line 2 - 5). The MovieFinder
needs to be
injected into the property MovieFinder
of the MovieLister
class (Line 4).
Nilsson writes that the information in the Spring .NET configuration file is redundant [Nilsson06, p. 380]. Most of this information is also available via the .NET type system. The redundant information leads to a potential maintenance problem. The configuration file has to be kept synchronous with the code. Changes in the code might need modifications in the configuration file. This maintenance problem can be reduced with a function called autowiring.
Spring .NET is capable to resolve the dependencies of a component
automatically. This is done by inspecting the component definition via
reflection. Listing 6 shows the same example as Listing 5 but uses the
autowiring function. By default, autowiring is deactivated and has to be enabled
for every object with the autowire
attribute (Line 3). Spring .NET knows
different modes for autowiring [Spring07, p. 38]. The mode byType
iterates
through all reference-type properties of the MovieLister
component and it
searches adequate objects for them.
1 <objects>
2 <object id="MyMovieLister" type="MovieLister.MovieLister,
3 MovieLister" autowire="byType" dependency-check="objects">
4 </object>
5
6 <object id="MyMovieFinder" type="MovieFinder.MovieFinder,
7 TextFileMovieFinder">
8 <constructor-arg index="0" value="Movies.txt"/>
9 </object>
10 </objects>
Listing 6: Extract of a Spring .NET configuration file with activated autowiring.
If autowiring does not find an adequate object for a property, it simply
ignores it. The mode "checking for dependencies" allows guaranteeing that all
properties are initialized with dependent objects (Line 3). If the dependency
check finds an unassociated property, the framework throws an
UnsatisfiedDependencyException
. The depencency-check
attribute knows further
modes but they are not important for the autowiring [Spring07, p. 39].
The application context represents the container that manages the lifecycle of the components. These containers can be structured into hierarchies. This is comparable to the WorkItem hierarchy of the Composite UI Application Block. The context provides a Service Locator style access to the registered components. This access can be used as an alternative to the Dependency Injection. Using the Service Locator is not recommended as the component would have a reference to the underlying framework. However, sometimes a component cannot be created by the framework factory and thus it is necessary to retrieve the dependent components manually.
One of the services provided by the application context is the loosely coupled event propagation. A component can register a publisher of which all .NET events are routed to interested subscribers. Other components can register a subscriber which receives all the events published by a specific type. The subscribers need to have a method that matches the signature of the event delegate. The event wiring cannot be done via the XML configuration file. Therefore a dependency to the application context is necessary.
Spring .NET is licensed under the Apache License, Version 2.07. Thus, it is an OSI Certified Open Source Software. It has only the restriction that the attribution and disclaimer has to be maintained. Important to note is that this software does not come with any warranties.
6 The official Website of Spring .NET: http://www.springframework.net.
7 Apache License, Version 2.0. See http://www.apache.org/licenses/LICENSE-2.0.