IObjectFactory是初始化、配置及管理对象的实际容器(按:它是所有容器的父接口)。对象间通常会相互协作,我们也可以说它们相互间具有依赖性。这些依赖性通过IObjectFactory的配置数据反映出来。(但某些依赖性从配置数据中是看不到的,比如运行时对象之间的方法调用。)

Spring.Objects.Factory.IObjectFactory接口有多个实现类。最常用的是 Spring.Objects.Factory.Xml.XmlObjectFactory。关于如何在代码中与IObjectFactory交互,与IObjectFactory交互。IApplicationContext接口所定义的增强功能将在IApplicationContext简介中讨论。

前文提到过,Spring.NET框架的核心原则是非侵入性。简单的说,就是应用程序的代码不需要对Spring.NET的API有任何依赖。然而,如果要通过IObjectFactory或Spring.Context.IApplicationContext接口充分利用IoC容器的功能,有时候还必须要初始化这两个接口的某个实现类。为此,可以在代码中使用new操作符来显式创建容器(在C#中,VB开发人员则使用New操作符。按:后文中,举凡涉及到含义为“管理对象的容器”而非特指接口的名称时,将原文中的IObjectFactory或IApplicationContext称为 “容器”或“IoC容器”);另一种更为简单的方式是在.NET应用程序的标准配置文件中用一个自定义节点来配置容器。一旦容器建立,应用程序代码就可能不再需要与之发生显式的交互了。

下面代码创建了XmlObjectFactory类的一个实例,XmlObjectFactory是IObjectFactory的实现类之一。我们假定在objects.xml文件中定义了要装配(按:装配的概念见后文)和发布的服务对象。将该文件的信息传递给XmlObjectFactory的构造器,即可创建一个容器,参见如下代码:
 
 
IResource input  =   new  FileSystemResource ( " objects.xml " );
IObjectFactory factory 
=   new  XmlObjectFactory(input);

代码中使用了Spring.NET的IResource接口。IResource能以简单统一的方式访问许多可用System.IO.Stream表示的IO资源。 IResource接口中将对IResource接口展开讨论。这些IO资源一般是独立的文件或者URL,但也可以是.NET程序集的内嵌资源。通过IResource接口,可以用简单的URI格式来描述资源的位置,比如可用file://object.xml来表示一个文件。此外,IResource也支持很多其它协议,如 http等。

前文提到IApplicationContext是IObjectFactory的超集,我们一般都会用IApplicationContext来作为容器。在创建容器时可以像上例一样用IResource实例化IApplicationContext接口的任何一个实现类。另外, IApplicationContext支持用多个配置文件创建容器(按:此处的配置文件是指包括了Spring.NET对象定义的XML文件,而非特指.config文件,下同):
IApplicationContext context  =   new  XmlApplicationContext(
    
" file://objects.xml " ,
    
" assembly://MyAssembly/MyProject/objects-dal-layer.xml " );

//  of course, an IApplicationContext is also an IObjectFactory...
IObjectFactory factory  =  (IObjectFactory) context;
 

下面是引用.NET程序集内嵌资源时的URI语法:assembly://<AssemblyName>/<NameSpace>/<ResourceName>
注意

若要在VS中创建一个内嵌的资源,必须在文件属性编辑器中将xml文件的Build Action设为Embedded Resource。并且,如果自上次成功建立项目之后,该属性的变更是本次所做的唯一更改,则需要显式的重新生成项目。如果使用NAnt建立项目,需要在 csc任务中添加一个<resources>节点。可参见Spring.Core.Tests项目中的build文件,该项目随 Spring.NET一起发布。

更好的创建方式是在标准.NET应用程序配置文件中(App.config或Web.config)添加自定义配置节点。以下的XML节点可以创建与前例相同的容器:

 
 
< spring >
  
< context  type ="Spring.Context.Support.XmlApplicationContext, Spring.Core" >
    
< resource  uri ="file://objects.xml" />
    
< resource  uri ="assembly://MyAssembly/MyProject/objects-dal-layer.xml" />
  
</ context >
</ spring >

<context>节点的type属性是可选的,在Windows应用中,其默认值就是Spring.Context.Support.XmlApplicationContext,所以下面的配置和上面完全相同:

 
 
< spring >
  
< context >
    
< resource  uri ="file://objects.xml" />
    
< resource  uri ="assembly://MyAssembly/MyProject/objects-dal-layer.xml" />
  
</ context >
</ spring >  

spring和context节点的名称不是任意的,必须是"spring"和"context",Spring.NET本身将 "spring/context"作为字符串常量定义在了AbstractApplicationContext类中以表示上下文的节点名称。若要引用由以上配置创建的容器,可使用下面的代码:

 
 
IApplicationContext ctx  =  ContextRegistry.GetContext();

ContextRegistry类既可用来初始化应用程序上下文,也可用来以服务定位器风格对容器中的对象进行访问。注意,使这一切成为可能的是Spring.Context.Support.ContextHandler类,该类实现了FCL的IConfigurationSectionHandler接口。必须在.NET配置文件的<configSections> 节点中注册这个类,如下所示:

 
 
< configSections >
  
< sectionGroup  name ="spring" >
    
< section  name ="context"  type ="Spring.Context.Support.ContextHandler, Spring.Core" />
  
</ sectionGroup >
</ configSections >

注册了这个节点处理器后,配置文件中的<spring>节点才能起作用。

在某些情况下,用户不需要以任何方式显式创建容器,Spring.NET可以自行创建。例如,Spring.NET中的Spring.Web模块可以将 IApplicationContext作为Web应用程序正常启动进程的一部分进行自动装载。目前正在研究如何为WinForms应用程序提供类似的支持
关于如何通过编程方式管理IObjectFactory,稍后再讲。下面我们先讨论IObjectFactory接口所使用的对象配置格式。(按:凡适用于IObjectFactory的内容,必定也适用于IApplicationContext)

基本上,IObjectFactory的配置信息由一个或多个对象定义构成。在基于XML的工厂中,这些对象定义表现为一个或多个< object>子节点,它们的父节点必须是<objects>(按:objects节点的xmlns元素是必需的,必须根据不同的应用添加不同的命名空间,请留意各个章节中的相关内容。

 
 
< objects  xmlns ="http://www.springframework.net"  
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"  
    xsi:schemaLocation
="http://www.springframework.net
        http://www.springframework.net/xsd/spring-objects.xsd"
>
  
< object  id ="..."  type ="..." >
  ...
  
</ object >
  
< object  id ="...."  type ="..." >
  ...
  
</ object >

  ...
</ objects >

随Spring.NET一起发布的schema文档可以简化对XML对象定义的验证过程。该文档是完全开放的(参见附录A,Spring.NET的spring-objects.xsd)。目前,除了验证XML文档外,该文档还有一个用途,就是在具备XSD感知能力的编辑器(比如VS.NET)内进行代码提示。可参考第二十四章,与Visual Studio.NET集成。在Spring.NET的网站上可以下载到spring-objects.xsd的最新版本。

XML对象定义也可以放在.NET的标准应用程序配置文件中。此时也需要为<objects>节点预先注册相应的节点处理器,类型为 Spring.Context.Support.DefaultSectionHandler。然后,就可以在.NET的.config文件中为一或多个容器配置对象定义了,如下所示:

 
 
< configuration >

  
< configSections >
    
< sectionGroup  name ="spring" >
      
< section  name ="context"  type ="Spring.Context.Support.ContextHandler, Spring.Core" />
      
< section  name ="objects"  type ="Spring.Context.Support.DefaultSectionHandler, Spring.Core"   />
    
</ sectionGroup >

  
</ configSections >

  
< spring >

    
< context >
      
< resource  uri ="config://spring/objects" />
    
</ context >

       
    
< objects  xmlns ="http://www.springframework.net" >
        ...
    
</ objects >

  
</ spring >

</ configuration >

上下文嵌套和从其它文件中导入对象定义会讨论创建配置文件时可用的其它节点。

我们也可以在配置文件中为IApplicationContext注册自定义的资源处理器、schema解析器、类型转换器和类型别名等等。IApplicationContext配置一节中将讨论这些内容。
 
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐