前面我们知道了什么是对象,什么是对象工厂,什么是应用程序上下文。这一次我们来看一下对象的装配。

  Spring.Net 中有多种装配对象的方式,装配这个词可能比较学术化,我们可以理解为对象的创建。

  Spring.Net 中常用的装配方式有 手动装配和自动装配。手动装配就是根据配置文件然后装配对象,而自动装配是指Spring.Net根据指定的自动模式查找相关属性并自动装配。这两种装配方式之下又分为 通过属性进行装配,通过构造器进行装配,通过静态工厂装配,通过实例工厂装配,泛型的装配等等。这些装配方式在下面会一一介绍。

4.4.1  手动装配

  在Spring.Net 中,手动装配 分为 多种装配方式,我们在下面介绍常用的几种装配方式:

  (1) 通过属性进行装配

  (2) 通过构造器进行装配

  (3) 通过静态工厂装配

  (4) 通过实例工厂装配

  (5) 对数组的装配

  (6) 对泛型集合的(List,Dictionary)装配

  (7) 泛型对象的装配

  (8) 事件的装配

4.4.1.1  通过属性进行装配

  在本小节,我们通过举例来说明,如何通过属性来装配对象,我们这里只讨论简单的属性,比如数组,集合,自定义类,这些属性我们放在后面一起讨论,这里还是举常用的Person与Dog的故事。

  一个Person类,拥有Id,Name,IsStudent,Dog(小狗)等属性,睡醒的方法(SleepLightly),还有一个ToString()的方法来输出信息

 1 using System;
2 using System.Collections.Generic;
3
4 namespace CnblogLesson_4_4_1.Model
5 {
6 /// <summary>
7 /// 人类
8 /// </summary>
9 public class Person
10 {
11 public Person() { }
12 public Person(string name) {
13 this.Name = name;
14 }
15 public Person(int id, string name, bool isStudent,Dog dog) {
16 this.Id = id;
17 this.Name = name;
18 this.IsStudent = isStudent;
19 this.Dog = dog;
20 }
21
22 /// <summary>
23 /// 编号
24 /// </summary>
25 public int Id { get; set; }
26
27 /// <summary>
28 /// 人的名称
29 /// </summary>
30 public string Name { get; set; }
31
32 /// <summary>
33 /// 是否是学生
34 /// </summary>
35 public bool IsStudent { get; set; }
36
37 /// <summary>
38 /// 小狗狗
39 /// </summary>
40 public Dog Dog { get; set; }
41
42 /// <summary>
43 /// 人拥有的物品
44 /// </summary>
45 public Object[] ObjArray { get; set; }
46
47 /// <summary>
48 /// 想要看的书
49 /// </summary>
50 public List<string> Books;
51
52 /// <summary>
53 /// 朋友们
54 /// </summary>
55 public Dictionary<string, string> Friends { get; set; }
56
57 /// <summary>
58 /// 睡醒了
59 /// </summary>
60 /// <param name="args"></param>
61 public void SleepLightly(string args)
62 {
63 Console.WriteLine("{0}叫了,把主人惊醒了", args);
64 }
65
66 /// <summary>
67 /// 重写ToString方法
68 /// </summary>
69 /// <returns></returns>
70 public override string ToString()
71 {
72 if (Dog == null)
73 {
74 Console.WriteLine("我是{0},我的Id是:{1},我是不是学生:{2},我没有小狗狗", Name, Id, IsStudent);
75 }
76 else {
77 Console.WriteLine("我是{0},我的Id是:{1},我是不是学生:{2},我的小狗叫:{3}", Name, Id, IsStudent, Dog.Name);
78 }
79 return String.Empty;
80 }
81 }
82 }

  小狗拥有一个Name的属性,一个事件,还有一个叫的方法:

 1 namespace CnblogLesson_4_4_1.Model
2 {
3 /// <summary>
4 /// 小狗狗
5 /// </summary>
6 public class Dog
7 {
8 public Dog() { }
9 public Dog(string name) {
10 this.Name = name;
11 }
12
13 /// <summary>
14 /// 小狗狗的名字
15 /// </summary>
16 public string Name { get; set; }
17
18 public event SleepLightly sleepLightly;
19
20 /// <summary>
21 /// 叫
22 /// </summary>
23 public void Cry()
24 {
25 if (sleepLightly != null)
26 {
27 sleepLightly.Invoke("猫");
28 }
29 }
30 }
31 }

  程序主方法:

 1 using System;
2 using Spring.Context;
3 using Spring.Context.Support;
4
5 namespace CnblogLesson_4_4_1
6 {
7 class Program
8 {
9 static void Main(string[] args)
10 {
11 //通过IApplicationContext来配置
12 IApplicationContext context = ContextRegistry.GetContext();
13 //4.4.1.1 通过属性进行装配
14 Person hexu = (Person)context.GetObject("hexu");
15 hexu.ToString();
16
17 Console.ReadKey();
18 }
19 }
20 }

  我们接下来创建一个Object.xml 来配置对象,将Object.xml设置为嵌入式资源,(这里一定要设置为潜入式资源)。

  属性的装配一般使用  <property name="Id" value="1" />  标签来表示,name表示要设置的属性名,如设置Id,value表示Id属性的值。

  装配简单的属性:

 1 <?xml version="1.0" encoding="utf-8" ?>
2 <objects xmlns="http://www.springframework.net">
3
4 <!--4.4.1.1 通过属性进行装配-->
5
6 <!--人类对象-->
7 <object id="hexu" type="CnblogLesson_4_4_1.Model.Person,CnblogLesson_4_4_1">
8 <!--设置编号-->
9 <property name="Id" value="1"/>
10 <!--设置姓名-->
11 <property name="Name" value="hexu"/>
12 <!--设置是否是学生-->
13 <property name="IsStudent" value="false"/>
14
15 <!--我的宠物为一个对象,这个对象的引用是id为kaqi的狗狗-->
16 <property name="Dog" ref="kaqi"/>
17 </object>
18
19 <!--宠物对象-->
20 <object id="kaqi" type="CnblogLesson_4_4_1.Model.Dog,CnblogLesson_4_4_1">
21 <property name="Name" value="卡琪"/>
22 </object>
23 </objects>

  装配自定义对象:

  标签 <property name="Dog" ref="kaqi"/> 的属性ref可以设置这个属性为一个引用,这个引用为id为kaqi的object标签。

  通过监视变量,我们可以看到,我们已经将属性装配成功。

4.4.1.2  通过构造器进行装配

  在上一小节我们讨论了如何通过属性来装配对象,这一小节我们讨论如何通过构造器装配。这一次,我们对Person类和 Dog 类分别增加了有参数构造函数。

  通过构造函数装配,需要使用到<constructor-arg name="Name" value="hexu"/>标签。Name表示构造函数参数名称,value表示该参数所赋的值。

  Objects.xml为下:

 1 <?xml version="1.0" encoding="utf-8" ?>
2 <objects xmlns="http://www.springframework.net">
3 <!--4.4.1.2 通过构造器进行装配-->
4
5 <!--有一个参数的构造函数-->
6 <object id="hexu_2_1" type="CnblogLesson_4_4_1.Model.Person,CnblogLesson_4_4_1">
7 <constructor-arg name="Name" value="hexu"/>
8 </object>
9
10 <!--有多个参数的构造函数-->
11 <object id="hexu_2_2" type="CnblogLesson_4_4_1.Model.Person,CnblogLesson_4_4_1">
12 <constructor-arg name="Id" value="1"/>
13 <constructor-arg name="Name" value="hexu"/>
14 <constructor-arg name="IsStudent" value="true"/>
15 <constructor-arg name="Dog" ref="kaqi_2"/>
16 </object>
17
18 <!--宠物对象_2-->
19 <object id="kaqi_2" type="CnblogLesson_4_4_1.Model.Dog,CnblogLesson_4_4_1">
20 <property name="Name" value="卡琪"/>
21 </object>
22 </objects>

  通过运行时监视变量可以看到,通过构造函数装载对象已经成功:

4.4.1.3  通过静态工厂进行装配

通过静态工厂来进行装配,就必须要有工厂对象,我们先来创建一个静态工厂对象

 1 using CnblogLesson_4_4_1.Model;
2 namespace CnblogLesson_4_4_1.Factory
3 {
4 public static class StaticFactory
5 {
6 public static Person CreateInstance() {
7 Dog dog = new Dog("卡琪");
8 Person person = new Person(1,"hexu",false,dog);
9 return person;
10 }
11 }
12 }

  再来看一下Objects.xml:

1 <?xml version="1.0" encoding="utf-8" ?>
2 <objects xmlns="http://www.springframework.net">
3 <!--4.4.1.3 通过静态工厂进行装配-->
4 <object name="staticFactory" type="CnblogLesson_4_4_1.Factory.StaticFactory,CnblogLesson_4_4_1" factory-method="CreateInstance"/>
5 </objects>

  使用静态工厂装配,需要配置一个工厂对象,并且设置静态工厂创建对象的方法factory-method为类中创建对象的方法。

  通过运行时监视变量,通过静态工厂装载对象已经成功:

4.4.1.4  通过实例工厂进行装配

  通过实例工厂方法装载对象与通过静态工厂方法装载对象的配置方式类似。此时,实例工厂方法所在的对象必须也要配置在同一容器(或父容器)中。

  如果要通过实例工厂方法装载对象,对象定义就不能包含type属性,而要用factory-object属性引用工厂方法所在的对象。注意,该属性值必须是包含工厂方法的对象的名称,且该对象必须定义在当前容器或父容器中。工厂方法的方法名则通过factory-method属性指定。(至于为什么不用type,而要使用factory-object呢?这是Spring.Net他们定义的规则。)这里我们也像通过静态工厂进行装配一样,通过实例工厂装配,需要定义一个实例工厂对象。

  实例工厂类:

 1 using CnblogLesson_4_4_1.Model;
2 namespace CnblogLesson_4_4_1.Factory
3 {
4 public class InstanceFactory
5 {
6 public Person CreateInstance() {
7 Dog dog = new Dog("卡琪");
8 Person person = new Person(1,"hexu",false,dog);
9 return person;
10 }
11 }
12 }

  Objects.xml 配置如下:

  使用实例工厂装配,需要配置一个工厂对象。如:Id=”instanceFactory”

  然后还需要一个实例对象id=” instancePerson”,并设置该实例是通过工厂对象创建,设置factory-object="instanceFactory",还要设置工厂创建实例的方法factory-method="CreateInstance"。

  再来看一下Objects.xml:

 1 <?xml version="1.0" encoding="utf-8" ?>
2 <objects xmlns="http://www.springframework.net">
3
4 <!--4.4.1.4 通过实例工厂进行装配-->
5
6 <!--工厂-->
7 <object id="instanceFactory" type="CnblogLesson_4_4_1.Factory.InstanceFactory, CnblogLesson_4_4_1" />
8 <!--创建的对象,factory-object所指向的是instanceFactory,表示通过instanceFactory工厂的CreateInstance方法来创建此对象-->
9 <object id="instancePerson" factory-method="CreateInstance" factory-object="instanceFactory" />
10
11 </objects>

  通过运行时监视变量,通过静态工厂装载对象已经成功:

4.4.1.5  对数组的装配

  前面我们一起讨论过属性的装配,但是前面我们讨论的都是一些简单的属性。这一节我们一起来讨论数组如何装配。

  Objects.xml 配置如下:

 1 <?xml version="1.0" encoding="utf-8" ?>
2 <objects xmlns="http://www.springframework.net">
3 <!--4.4.1.5 对数组的装配-->
4 <!--人类对象-->
5 <object id="hexu_2_5" type="CnblogLesson_4_4_1.Model.Person,CnblogLesson_4_4_1">
6 <!--设置姓名-->
7 <property name="Name" value="hexu"/>
8 <property name="ObjArray">
9 <set>
10 <value>亲人</value>
11 <value>朋友</value>
12 <value>工作</value>
13 <value>程序</value>
14 </set>
15 </property>
16 </object>
17 </objects>

  通过运行时监视变量,通过静态工厂装载对象已经成功:

4.4.1.6  对泛型的装配之List

  这一小节,我们一起来讨论对List集合的装载。

  Objects.xml 配置如下:

 1 <?xml version="1.0" encoding="utf-8" ?>
2 <objects xmlns="http://www.springframework.net">
3
4 <!--4.4.1.6 对泛型的装配之List集合-->
5 <!--人类对象-->
6 <object id="hexu_2_6" type="CnblogLesson_4_4_1.Model.Person,CnblogLesson_4_4_1">
7 <!--设置姓名-->
8 <property name="Name" value="hexu"/>
9 <property name="Books">
10 <!--设置集合的类型-->
11 <list element-type="string">
12 <value>重构</value>
13 <value>WCF全面解析</value>
14 <value>设计模式:可复用面向对象软件的基础</value>
15 </list>
16 </property>
17 </object>
18
19 </objects>

  标签<list element-type="string">....</list>表示C#中的List<string>,value 表示 元素的值

  通过运行时监视变量,通过静态工厂装载对象已经成功:

4.4.1.7  对泛型的装配之Dictionary集合

  这一小节,我们一起来讨论对Dictionary集合的装载。

  Objects.xml 配置如下:

 1 <?xml version="1.0" encoding="utf-8" ?>
2 <objects xmlns="http://www.springframework.net">
3
4 <!--4.4.1.7 对泛型的装配之Dictionary集合-->
5
6 <!--人类对象-->
7 <object id="hexu_2_7" type="CnblogLesson_4_4_1.Model.Person,CnblogLesson_4_4_1">
8 <!--设置姓名-->
9 <property name="Name" value="hexu"/>
10 <property name="Friends">
11 <!--设置集合的类型-->
12 <dictionary key-type="string" value-type="string">
13 <entry key="ZG" value="张哥"/>
14 <entry key="LG" value="李哥"/>
15 <entry key="WG" value="王哥"/>
16 </dictionary>
17 </property>
18 </object>
19
20 </objects>

  标签<dictionary key-type="string" value-type="string">....</dictionary>表示C#中的Dictionary<string,string>,key-type 表示 键的类型,value-type 表示 值的类型。entry则表示每个元素。  

  通过运行时监视变量,通过静态工厂装载对象已经成功:

4.4.1.8  泛型对象的装配

  Spring.Net 中对泛型对象的创建方法和普通对象是一样的。但有一个很细微的差别。

  在为泛型类对象指定type属性的时候要注意:

  第一,   左尖括号<要替换成字符串“&lt;”,因为在XML中左尖括号会被认为是小于号。可读性来讲,我们都知道这并不是理想的方式。

  第二,type参数值中不能包含程序集的名称,因为程序集名称要求和类型全名用逗号隔开,而在这里逗号已经被用来分隔泛型类的类型参数了。将来可能会用其它字符代替这两个符号,但目前还没找到更具可读性的方案。若要提高可读性,建议使用类型别名。

  先来看一下GenericClass.cs的定义:

1 namespace CnblogLesson_4_4_1.Generic
2 {
3 public class GenericClass<T>
4 {
5 public T obj { get; set; }
6 }
7 }

  Objects.xml 配置如下:

1 <?xml version="1.0" encoding="utf-8" ?>
2 <objects xmlns="http://www.springframework.net">
3
4 <!-- 4.4.1.8 泛型类的装配 如: GenericClass<string> -->
5 <object id="hexu_2_8" type="CnblogLesson_4_4_1.Generic.GenericClass&lt;string>, CnblogLesson_4_4_1" >
6 <property name="obj" value="generic"/>
7 </object>
8
9 </objects>

  通过运行时监视变量,通过静态工厂装载对象已经成功:

5.4.1.9  事件的装配

  Spring.NET的IoC框架中,还提供事件的注入。通过事件的注入,可以使架构体系的耦合降到最低。仍然使用一个例子:主人正在睡觉,小偷来了,然后小狗发现小偷就汪汪叫,主人被小狗的叫声惊醒。

  创建一个 惊醒的委托:

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace CnblogLesson_4_4_1.Model
7 {
8 public delegate void SleepLightly(string args);
9 }

  配置Objects.xml 文件:

 1 <?xml version="1.0" encoding="utf-8" ?>
2 <objects xmlns="http://www.springframework.net">
3 <!--4.4.1.9事件注入-->
4
5 <!--先装载小狗对象-->
6 <object id="observer_dog" type="CnblogLesson_4_4_1.Model.Dog, CnblogLesson_4_4_1" />
7 <!--装载主人对象,主人需要监听小狗对 惊醒事件的触发,当小狗叫,主人调用睡醒的方法-->
8 <object id="observer_person" type="CnblogLesson_4_4_1.Model.Person, CnblogLesson_4_4_1">
9 <!--使用到listener监听器,ref表示主人要监听的小狗,event表示主人监听小狗的哪个事件,method表示,当监听到的事件触发时,调用自己的睡醒事件-->
10 <listener event="sleepLightly" method="SleepLightly">
11 <ref object="observer_dog"/>
12 </listener>
13 </object>
14
15 </objects>

  装配事件需要使用到<listener event="sleepLightly" method="SleepLightly">...</listener>标签,由于在Dog.cs 和 Person.cs 中都已经写好了 代码,现在只需要通过Objects.xml来动态设置参数。<listener event="sleepLightly" method="SleepLightly">...</listener>标签中,event就是用来指定,需要设置Dog.cs类中的哪个事件(上面是设置sleepLightly事件),method表示,这个事件的值是哪个方法。使用<ref object="observer_dog"/>表示,这个事件的参数。您看,在Dog.cs 类中,我传了一个字符串“猫”作为参数,最后输出结果为“猫叫了,把主人惊醒了”!

  通过运行时监视变量,通过静态工厂装载对象已经成功:

  到目前为止,Spring.Net 中大部分手动装配对象方式 都在上面的文章里了,在下面的一章里,会谈到不常用的自动装配方式。

第四章 Spring.Net 如何管理您的类___对象的手动装配的更多相关文章

  1. 第四章 Spring.Net 如何管理您的类___对象的自动装配

    由于这几天都比较忙,所以对笔记暂时没有更新. Spring.NET具有自动装配的能力,也就是说,Spring.NET可以通过对象的定义自动分辨某个对象的协作对象.自动装配是针对单个对象(按:针对每个协 ...

  2. 第四章 Spring.Net 如何管理您的类___对象、对象工厂和应用程序上下文

    在前面一章我们介绍了依赖注入,控制反转的概念,以及自己动手搭建了一下Spring.Net的环境.通过这些操作,我们知道了Spring.Net 的核心是使用依赖注入或控制反转这种思想来管理业务对象,降低 ...

  3. 第四章 Spring.Net 如何管理您的类___对象的生命周期链

    各位,实在不好意思,因为有事,博客几天没更新了.前面有童鞋提到,配置 Objects.xml 路径的相关问题,这些东西是 IResource 接口的一些内容.在下一章会详细介绍. 传统的Net应用中, ...

  4. 第四章 Spring.Net 如何管理您的类___对象的作用域

    Spring.Net 中对象的作用域,就是描述对象的部署模式 ,Spring.Net 中对象可以通过两种模式布署: ① singleton(单例模式) ② 非singleton 也叫非单例模式(或者叫 ...

  5. 第四章 Spring.Net 如何管理您的类___对象的初始化方式

    在 Spring.Net 中对象初始化的方式分为两种: ① 急切实例化,也就是说 Spring.Net 容器初始化的时候将对象先实例化出来. ② 延迟实例化,也就是说我们在调用 GetObject 方 ...

  6. 第四章 Spring.Net 如何管理您的类___统一资源访问接口

    在前面章节有童鞋提到过 关于配置文件 Objects.xml 路径的相关问题,这些东西是 IResource 接口的一些内容,接下来就详细介绍一下 IResource 接口. IResource 接口 ...

  7. 第四章 Spring.Net 如何管理您的类___让对象了解自己的容器

    我们在开发中,经常需要让对象了解自己所在的容器的信息,例如,有时我们需要让对象知道,对象所在容器的引用是什么,或者是对象在容器中的名称是什么 .Spring.Net 中提供了两个接口,我们使用这两个接 ...

  8. 第四章 Spring.Net 如何管理您的类___自定义对象行为

    Spring.Net 一直讲求 ” 配置应用程序“,有一种需求在实际开发中不太常用,却非常有用 -> 配置对象的行为,Spring.Net 也能够完美的实现.Spring.Net 通过几个专门的 ...

  9. 第四章 Spring.Net 如何管理您的类___IObjectPostProcessor接口

    官方取名叫 对象后处理器 (object post-processor) , 听起来很高级的样子啊!实际上就是所有实现了这个接口的类,增加了两个方法. Spring.Objects.Factory.C ...

随机推荐

  1. gulp入门与一些基本设置

    这里是gulp入门的一些操作,实现了编译sass文件.压缩.合并.添加版本号等基本功能. 友情提示,如果npm出现无法下载可以安装 cnpm.在安装完Nodejs 后 npm install cnpm ...

  2. 在IIS6上部署WebService

    在IIS6上部署WebService 2016-12-07 目录: 1 创建web service项目2 部署WebService3 浏览页面 1 创建web service项目 返回 用Visual ...

  3. 搞清tomcat中的编解码

    http://www.xuebuyuan.com/1287083.html *********************************** 经常会被乱码问题搅得头晕脑胀.事实上,乱码问题涉及的 ...

  4. 如何把高版本的sqlserver 还原到低版本的 sqlserver

    本例为sql2012 还原到sql2008. 要实现的功能是把sql2012的数据库备份到sql2008,数据库名字为Test,并且这两个数据库在不同的电脑中. 微软的软件设计方案基本上都是新版本兼容 ...

  5. python学习笔记(17)--eclipse和pydev的安装及汉化

    说明: 1. 本来一直用sublime的REPL跑python,不过在用爬虫下载图片输出页数的时候,由于输出太多行会卡住,而IDLE已经受够了,写起代码来实在是不好用.之前其实也写过一篇文章探讨过各种 ...

  6. 通过SiteMapDataSource动态获取SiteMap文件进行权限设置

    最近做一个用ASP.NET做一个小项目,用户不是很多,功能不算太复杂,但是做到权限控制的时候有点犯难,这么一个小系统如果全部做一个大的复杂的权限控制觉得成本不划算,打算用Treeview ,根据不同的 ...

  7. JS地毯式学习三

    1. 插件是一类特殊的程序 . 他可以扩展浏览器的功能 , 通过下载安装完成 . 比如 , 在线音乐.视频动画等等插件. // 检测非 IE 浏览器插件是否存在function hasPlugin(n ...

  8. zip文件内存中解压读取

    // 构造zip输入流 ZipInputStream zip = new ZipInputStream(fis,Charset.forName("gbk")); byte[] tm ...

  9. MS-SQL 删除数据库所有的表

    godeclare @tbname varchar(250)declare #tb cursor for select name from sysobjects where objectpropert ...

  10. iOS边练边学--transform的简单介绍并且用transform实现键盘处理

    一.transform:形变属性,能完成功能:平移,缩放,旋转 <平移> // 根据给的移动距离平移 self.tempView.transform = CGAffineTransform ...