16.2.4
构造器注入(Constructor Injection)
我们来定义在应用程序文件里IMovieFinder接口的另外一种执行。
...
<object name="AnotherMovieFinder"
type="Spring.Examples.MovieFinder.ColonDelimitedMovieFinder, Spring.Examples.MovieFinder">
</object>
...
XML代码片断描述了IMovieFinder使用一个边界文本作为他的电影源的执行。这个类的C#源码定义了一个单独的获得System.IO.FileInfo作为它的构造参数的构造器。当这个对象定义完成,尝试在应用程序里用如下一条代码获得IApplicationContext对象:
IMovieFinder finder = (IMovieFinder) ctx.GetObject ("AnotherMovieFinder");
结果会产生Spring.Objects.Factory.ObjectCreationException异常,因为Spring.Examples.MovieFinder.ColonDelimitedMovieFinder类没有没有参数的默认构造器。如果我们想要使用这个ImovieFinder接口的实例,我们不得不提供一个适当的构造参数
...
<object name="AnotherMovieFinder"
type="Spring.Examples.MovieFinder.ColonDelimitedMovieFinder, Spring.Examples.MovieFinder">
<constructor-arg index="0" value="movies.txt"/>
</object>
...
可以想象得到,<constructor-arg/>元素是用来给管理的对象的构造器提供构造器参数的。Spring.NET IoC容器使用System.ComponentModel.TypeConverter特殊化来转换movies.txt字符串为System.IO.FileInfo的实例作为Spring.Examples.MovieFinder.ColonDelimitedMovieFinder的构造参数的广泛支持(参见第4.3章节“类型转换”)
现在我们有了ImovieFinder接口的2种获得方式,它们都有从例子程序的配置文件中获得独特的对象定义,如果我们想,我们可以转换MyMovieLister对象的获得如下:
...
<object name="MyMovieLister"
type="Spring.Examples.MovieFinder.MovieLister, Spring.Examples.MovieFinder">
<!-- lets use the colon delimited implementation instead -->
<property name="movieFinder" ref="AnotherMovieFinder"/>
</object>
<object name="MyMovieFinder"
type="Spring.Examples.MovieFinder.SimpleMovieFinder, Spring.Examples.MovieFinder"/>
</object>
<object name="AnotherMovieFinder"
type="Spring.Examples.MovieFinder.ColonDelimitedMovieFinder, Spring.Examples.MovieFinder">
<constructor-arg index="0" value="movies.txt"/>
</object>
...
注意没有必要重新编译程序来实现这个执行的改变。简单的改变应用程序的配置文件,然后重新启动引用程序就会得到Spring .NET IoC容器注入到IMovieFinder接口边界获得MyMovieLister对象。