Anyone that has worked with Spring.Net is probably familiar with configuring the IOC container using an XML document. A typical example would be:
2:
3: <objects xmlns="http://www.springframework.net"
4: xmlns:v='http://www.springframework.net/validation'
5: xmlns:aop="http://www.springframework.net/aop"
6: xmlns:db="http://www.springframework.net/db"
8:
1: <?xml version="1.0" encoding="utf-8"?>
9: <object id="ConsoleWriter" type="SimpleCalculatorWithComplexTree.Writers.ConsoleWriter" singleton="false" >
10: <constructor-arg name="formatter" ref="HexFormatter" />
11: </object>
12:
13: <object id="Calculator" type="SimpleCalculatorWithComplexTree.Calculator" singleton="false">
14: <constructor-arg name="writer" ref="ConsoleWriter" />
15: </object>
16:
17: <object id="HexFormatter" type="SimpleCalculatorWithComplexTree.Formatters.HexFormatter" singleton="false" >
18:
19: </object>
20:
21: </objects>
The last couple of years has seen an anti-XML movement begin to form. In the world of IOC containers, this has materialized as a movement away from XML configuration and more towards using code constructs and “convention over configuration.” I’m not against XML. After all, almost everything has a place.
I recently did a presentation on Spring.Net for a .NET user group. I wanted to introduce the IOC container without overwhelming people with XML. A quick search found an article about XMLless configuration of the container. This approach felt like it would be a distraction from my goal of getting to the container.
Luckily I stumbled into at article from early 2008 that discussed the configuration api. From this I was able to create this method that extends the GenericApplicationContext and allows for easy registration of a type in the container:
1: Imports System.Runtime.CompilerServices
2: Imports Spring.Context.Support
3: Imports Spring.Objects.Factory.Support
4:
5: Public Module SpringExtension
6:
7: <Extension()>
8: Public Sub RegisterType(Of T)(ByVal ctx As GenericApplicationContext, ByVal builderConfig As Action(Of ObjectDefinitionBuilder))
9: Dim objectDefinitionFactory As IObjectDefinitionFactory = New DefaultObjectDefinitionFactory()
10:
11: Dim builder As ObjectDefinitionBuilder = ObjectDefinitionBuilder.RootObjectDefinition(objectDefinitionFactory, GetType(T))
12: builderConfig.Invoke(builder)
13:
14: ctx.RegisterObjectDefinition(builder.ObjectDefinition.ObjectType.Name, builder.ObjectDefinition)
15:
16: End Sub
17:
18: End Module
Here’s a quick example of its use:
1: Dim ctx = New GenericApplicationContext()
2:
3: ctx.RegisterType(Of Calculator)(Sub(b As ObjectDefinitionBuilder) b _
4: .SetAutowireMode(Spring.Objects.Factory.Config.AutoWiringMode.AutoDetect) _
5: .SetSingleton(False))
6:
7: ctx.RegisterType(Of HexFormatter)(Sub(b As ObjectDefinitionBuilder) b _
8: .SetAutowireMode(Spring.Objects.Factory.Config.AutoWiringMode.AutoDetect) _
9: .SetSingleton(False))
10:
11: ctx.RegisterType(Of ConsoleWriter)(Sub(b As ObjectDefinitionBuilder) b _
12: .SetAutowireMode(Spring.Objects.Factory.Config.AutoWiringMode.AutoDetect) _
13: .SetSingleton(False))