Dependency Injection with Spring.Net
Notice that the NumberArray class holds a reference to one of the sort strategies as defined by the ISortStrategy interface. The NumberArray class doesn't have any direct reference to a concrete implementation of the strategy. So, how does the strategy get set up, then? Though Spring.Net Dependency Injection, of course! Take a look at the Spring.Net mapping:
<!-- Strategies --> <object name="BubbleSortStrategy" type="BubbleSortStrategy, __Code" singleton="true"> </object> <object name="HeapSortStrategy" type="HeapSortStrategy, __Code" singleton="true"> </object> <object name="QuickSortStrategy" type="QuickSortStrategy, __Code" singleton="true"> </object> <!-- Number Arrays --> <object name="NumberArray_BubbleSort" type="NumberArray, __Code" singleton="false"> <constructor-arg name="sortStrategy" ref="BubbleSortStrategy" /> </object> <object name="NumberArray_HeapSort" type="NumberArray, __Code" singleton="false"> <constructor-arg name="sortStrategy" ref="HeapSortStrategy" /> </object> <object name="NumberArray_QuickSort" type="NumberArray, __Code" singleton="false"> <constructor-arg name="sortStrategy" ref="QuickSortStrategy" /> </object>
Listing 7: Number Array & Strategies Mappings
So, as you can see from the mappings, there are three different ways to initialize the NumberArray, each with a different strategy object injected. The code using a NumberArray object just needs to ask Spring.Net for a "NumberArray_BubbleSort", "NumberArray_BubbleSort", or "NumberArray_BubbleSort" object. Each NumberArray object will look the same to the code using it, but behind the scenes the currently initialized strategy will be used to run the sort functionality.
To see an example of the code above being used in a simple web app, check out the example code for this article: Download Code Examples.
Another important concept employed by Spring.Net is the use of the singleton pattern. You will notice in the examples above that there is a "singleton" property for each object mapping, but what does this mean? To understand this further, look at the singleton pattern:
Figure 4: Singleton Pattern
Basically, the singleton pattern ensures that there is only one instance of a class and that you can retrieve and use that single instance through a global point of access. Usually, this is done by implementing a class with a private constructor so it can only be instantiated internally. Then, the class instantiates a single instance of the object within itself and provides a public static reference to the instance so the application can reference it. This pattern is very similar to using static functions and properties within a class, but it provides a bit more flexibility and control because you get an actual object instance to work with.
Spring.Net takes full advantage of the singleton pattern by allowing users to specify objects as singleton or not. So, for instance, if you look at the NumberArray example above, the NumberArray objects defined in the Spring.Net configuration are not singletons but the strategy objects defined are singletons. What this means is that each time you ask Spring.Net for a NumberArray object, it will create a new NumberArray object instance. This makes sense for the NumberArrays because you can have several number arrays in different states with different numbers in the array.
The strategy classes, however, are not really concerned with state. They have no properties that need to be maintained. They are simply used as plug and play functionality, so it makes sense to define them as singletons. When Spring.Net is asked for a strategy object, Spring.Net always returns the same singleton instance. And, when Spring.Net injects the strategies into the NumberArray objects, Spring.Net always injects the same strategy instance. Each strategy object will have only one instance per application.
It is important to note that the singleton pattern is not really necessary in the NumberArray example above. Each NumberArray could use a new instance of a strategy object, and everything would work just as well. The only problem with this case, though, is that your application will use extra time to create all the new objects, use extra memory to store each of the new objects, and then use extra time to clean up the objects when they are no longer being used. Generally, it is a much better practice to use the singleton pattern when it makes sense. It will save your application time and space because only one object will be initialized and it will only happen once.
Quick N-Tier Example
For the last example, look at a common usage of Spring.Net Dependency Injection where an application is split into multiple tiers and wired together by Spring.Net.
Anyone involved in larger applications has probably encountered the concept of N-tier application architecture. The basic idea is that an application is split up into multiple tiers of functionality. Each tier handles its own concerns and only communicates with the tier above/below it. For example, you might have a 3-tier application architecture as such:
Figure 5: 3-Tier Application Architecture Example
Page 4 of 6