.NET 企业库 知识分享--知识产生力量,成功源于分享!
RSS

导航







专业.NET技术社区

专业.NET技术社区


快速搜索

高级搜索 »

注意:此页面是Spring.NET框架 1.1 参考文档的一部分。


编辑

5.1. 简介

(Available in 1.0)

IObjectWrapper是Spring.NET核心类库的一个底层接口,一般情况下开发人员不会直接去使用它,但由于本文档是一份参考文档,我们认为还是应该对此核心接口稍作阐述。开发人员可以用这个接口来实现数据绑定,因为数据绑定恰好是IObjectWrapper要解决的问题。

顶部



编辑

5.2. 使用IObjectWrapper接口管理对象

IObjectWrapper接口和ObjectWrapper类是Spring.Objects命名空间下的重要类型。 IObjectWrapper接口的功能包括(单个或成批的)设置和读取属性的值、获取属性的描述信息(即 System.Reflection.PropertyInfo类的实例)以及查询属性的可读/写性。IObjectWrapper支持嵌套属性,可以为任意深度的属性赋值。该接口一般不会在应用程序代码中直接使用,而是由Spring.NET框架内部的类使用,比如IObjectFactory的各个实现类就用到了这个接口。

IObjectWrapper的名字基本可以说明它的工作方式:将一个对象包装起来,再对其进行操作,比如读/写被包装对象的属性值等。

注意:如果不打算直接使用IObjectWrapper接口,那么本节的内容可以跳过不看。

顶部

编辑

5.2.1. 读、写普通及嵌套的属性

IObjectWrapper接口中设置和读取属性值的方法分别是SetPropertyValue()和GetPropertyValue(),这两个方法都有很多重载,详细内容可参考API文档。

SetPropertyValue()和GetPropertyValue()方法可以用属性路径来查找属性。属性路径是一个表达式,实现了IObjectWrapper的类可以根据该路径查找被包装对象的属性,下面是一些例子...

表 5.1. 属性路径的例子
路径解释
name表示被包装对象中名为name的属性。
account.name表示被包装对象中account属性的name属性。
account[2]表示被包装对象中account属性索引器的第3个元素。索引属性一般用于访问集合字段,也可以访问任何支持索引的类型。

我们来看一个使用IObjectWrapper读写对象属性的例子,先看下面两个类:

[C#]
public class Company
 {
 private string name;
 private Employee managingDirector;

 public string Name
 {
 get { return this.name; }
 set { this.name = value; }
 }
 
 public Employee ManagingDirector
 {
 get { return this.managingDirector; }
 set { this.managingDirector = value; }
 }
}

[C#]
public class Employee
{
 private string name;
 private float salary;
 
 public string Name
 {
 get { return this.name; }
 set { this.name = value; }
 }

 public float Salary
 {
 get { return salary; }
 set { this.salary = value; }
 }
}

在下面的代码中,用IObjectWrapper通过属性名来读写被包装的Company和Employee对象的属性:

[C#]
Company c = new Company();
IObjectWrapper owComp = new ObjectWrapper(c);
// setting the company name...
owComp.SetPropertyValue("name", "Salina Inc.");
// can also be done like this...
PropertyValue v = new PropertyValue("name", "Salina Inc.");
owComp.SetPropertyValue(v);

// ok, let's create the director and bind it to the company...
Employee don = new Employee();
IObjectWrapper owDon = new ObjectWrapper(don);
owDon.SetPropertyValue("name", "Don Fabrizio");
owComp.SetPropertyValue("managingDirector", don);

// retrieving the salary of the ManagingDirector through the company
float salary = (float)owComp.GetPropertyValue("managingDirector.salary");

注意Spring.NET是遵循CLS(Common Language Specification,通用语言规范)的,任何要解析为属性、事件或类型的字符串都是大小写无关的。所以在上面的例子中,虽然C#是大小写敏感的,我们也可以用小写的"name"来设置Employee对象的Name属性。下面的例子(仍使用上面的类型)更能说明这个问题...

[C#]
// ok, let's create the director and bind it to the company...
Employee don = new Employee();
IObjectWrapper owDon = new ObjectWrapper(don);
owDon.SetPropertyValue("naMe", "Don Fabrizio");
owDon.GetPropertyValue("nAmE"); // gets "Don Fabrizio"

IObjectWrapper owComp = new ObjectWrapper(new Company());
owComp.SetPropertyValue("ManaGINGdirecToR", don);
owComp.SetPropertyValue("mANaGiNgdirector.salARY", 80000);
Console.WriteLine(don.Salary); // puts 80000

Spring.NET的这种大小写无关的处理方式是遵循CLS规范的,不是什么功能缺陷。如果您正好有这样一个类型,其中部分属性、事件或者方法仅能以大小写来区分,那么您就需要考虑重构代码了,因为一般说来都会认为这不是好的编码风格。

顶部

编辑

5.2.2. 其它功能

除了上一小节讲到的功能,IObjectWrapper还有一些其它功能,虽然不值得单独花一小节来讲,不过您可能会比较感兴趣:
  • 检测属性的可读性和可写性。可以用IsReadable()和IsWritable()方法检测某个属性是否可读或可写。
  • 获取PropertyInfo实例。使用GetPropertyInfo(string)和GetPropertyInfos()方法,可以获取System.Reflection.PropertyInfo类的实例,如果需要访问被包装对象属性的元数据,可以用这两个方法。

顶部



编辑

5.3. 类型转换

如果已经用标准的.NET机制将一个类型转换器和某个类型关联了起来(看下面的代码),Spring.NET就会使用这个类型转换器进行类型转换。

[C#]
[TypeConverter (typeof (FooTypeConverter))]
public class Foo
{
}

Spring.Core中的很多类都用到了System.ComponentModel命名空间下的TypeConverter类,这些类“...可以用统一的方式来进行类型转换和普通值及子属性的访问。”。[4]

例如,我们可以用可读性较好的格式表示一个日期(比如1984年8月30日),也可以将它转换为原始的日期格式(或者)System.DateTime类型。在. NET中,通过为某个类型应用TypeConverterAttribute特性,可以为它指定类型转换器。Spring.NET则提供了另外几种关联类型转换器的方式。Spring.NET可以进行某些无法用标准方式完成的转换,比如,Spring.Core程序集中有一个类型转换器,可以将以逗号分隔的字符串转换为字符串数组。用Spring.NET注册了自定义类型转换器之后,IObjectWrapper接口就知道如何将某个值转换为指定类型了。

我们在IoC容器中配置对象的属性时,Spring.NET就在后台应用了TypeConverter。当用字符串值定义某个对象的属性(比如通过 XML定义来声明),且这个属性的类型是System.Type时,Spring.NET会尝试用RuntimeTypeConverter将字符串值转换为Type对象。下面这个例子就将字符串“Example.Xml.SAXParser”自动转换为了相应的Type对象:

<objects xmlns="http://www.springframework.net">
<object id="parserFactory" type="Example.XmlParserFactory, ExamplesLibrary"
destroy-method="Close">
 <property name="ParserClass" value="Example.Xml.SAXParser, ExamplesLibrary"/>
</object>
</objects>

[C#]
public class XmlParserFactory
{
	private Type parserClass;
	
	public Type ParserClass
	{
	get { return this.parserClass; }
	set { this.parserClass = value; }
	}
	
	public XmlParser GetParser ()
	{
	return Activator.CreateInstance (ParserClass);
	}
}

顶部



编辑

5.3.1. 转换枚举类型

枚举类型的默认转换器是System.ComponentModel.EnumConverter,它会将枚举值的名字转换为对应的值。比如说, TestObject类有个FileMode枚举类型的属性,该枚举有个名为Create的值,那么这个类的对象就可以这么配置:

<object id="rod" type="Spring.Objects.TestObject, Spring.Core.Tests">
 <property name="Name" value="Rod"/>
 <property name="FileMode" value="Create"/>
</object>

顶部



编辑

5.4. 内置类型转换器

Spring.NET预先注册了一部分自定义类型转换器(例如将以字符串表示的类型名转换为System.Type对象的转换器)。这些转换器都定义在Spring.Core程序集的Spring.Objects.TypeConverters命名空间下,如下表所示:

表 5.2. 内置类型转换器
类型解释
RuntimeTypeConverter将字符串表示的类型名转换为实际的System.Type对象
FileInfoConverter将字符串转换为System.IO.FileInfo对象
StringArrayConverter将以逗号分隔的字符串列表转换为字符串数组,反之亦可
UriConverter将字符串表示URI转换为实际的URI对象
StreamConverter将Spring的IResource URI的字符串表示形式转换为InputStream对象
ResourceConverter将用字符串表示的Spring IResource格式的URI转换为IResource对象
ResourceManagerConverter将一个以逗号分隔的两段字符串(资源名,程序集名)转换为一个System.Resource.ResourceManager对象
RGBColorConverter将以逗号分隔的红,绿,蓝值转换为System.Drawing.Color结构

Spring.NET会使用标准的.NET机制来解析对象的类型,这些机制包括但不限于:检查和应用程序相关的所有配置文件、检查GAC以及使用程序集探测机制等。
[4] 原文为“... provides a unified way of converting types of values to other types, as well as for accessing standard values and subproperties.”。有关自定义TypeConverter的详细内容可以参见MSDN网站,相关内容可以搜索Implementing a Type Converter。

顶部

.NET 藏经阁 | | 版权所有 ©2008 entlib.net.cn