Console.WriteLine(o);
}
}
}
}
}
}
[Spring.NET IoC] 之二:配置文件
Spring.NET IoC 支持2种配置文件方式:
1. 应用程序配置文件
app.config / web.config
1. 应用程序配置文件
app.config / web.config
<?xml version="1.0" encoding="utf-8" ?>
<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">
<object >
</object>
</objects>
</spring>
</configuration>
<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">
<object >
</object>
</objects>
</spring>
</configuration>
test.cs
IApplicationContext context = ContextRegistry.GetContext();
object o = context.GetObject("HelloWorld");
object o = context.GetObject("HelloWorld");
2. 独立配置文件
springtest.xml
<?xml version="1.0" encoding="utf-8"?>
<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 >
</object>
</objects>
<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 >
</object>
</objects>
test.cs
IApplicationContext context = new XmlApplicationContext(@"springtest.xml");
object o = context.GetObject("HelloWorld");
object o = context.GetObject("HelloWorld");
建议使用独立的配置文件,应用程序配置文件已经被塞入太多内容了。Spring.NET 还支持很多高级的
[Spring.NET IoC] 之三:获取对象
</object>
</objects>
</objects>
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using Spring.Core;
using Spring.Context;
using Spring.Context.Support;
namespace ConsoleApplication1.SpringNet
{
public class HelloWorld
{
private string name;
private int age;
public HelloWorld(string name, int age)
{
this.name = name;
this.age = age;
}
public override string ToString()
{
return String.Format("Name={0}; Age={1}", name, age);
}
}
public class Program
{
static void Main(string[] args)
{
IApplicationContext context = new XmlApplicationContext(@"Config\Spring.xml");
object o = context.GetObject("HelloWorld");
Console.WriteLine(o);
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Threading;
using Spring.Core;
using Spring.Context;
using Spring.Context.Support;
namespace ConsoleApplication1.SpringNet
{
public class HelloWorld
{
private string name;
private int age;
public HelloWorld(string name, int age)
{
this.name = name;
this.age = age;
}
public override string ToString()
{
return String.Format("Name={0}; Age={1}", name, age);
}
}
public class Program
{
static void Main(string[] args)
{
IApplicationContext context = new XmlApplicationContext(@"Config\Spring.xml");
object o = context.GetObject("HelloWorld");
Console.WriteLine(o);
}
}
}
需要注意的是 Spring.NET IoC 缺省对象创建方式是 "Singleton",我们写个例子验证一下。
object o = context.GetObject("HelloWorld");
object o2 = context.GetObject("HelloWorld");
Console.WriteLine(object.ReferenceEquals(o, o2)); // output: true
object o2 = context.GetObject("HelloWorld");
Console.WriteLine(object.ReferenceEquals(o, o2)); // output: true
我们只需在配置文件中添加一个标记即可改变为非 Singleton 方式。
<?xml version="1.0" encoding="utf-8"?>
<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 />
</object>
</objects>
<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 />
</object>
</objects>
2. 静态工厂方法创建对象
我们提供另外一个 HelloWorld 类,该类型没有公用构造方法,只能通过静态方法创建对象。
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using Spring.Core;
using Spring.Context;
using Spring.Context.Support;
namespace ConsoleApplication1.SpringNet
{
public class HelloWorld
{
private HelloWorld()
{
}
public static HelloWorld Create()
{
return new HelloWorld();
}
}
public class Program
{
static void Main()
{
IApplicationContext context = new XmlApplicationContext(@"Config\Spring.xml");
object o = context.GetObject("HelloWorld");
object o2 = context.GetObject("HelloWorld");
Console.WriteLine(object.ReferenceEquals(o, o2)); // output: true
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Threading;
using Spring.Core;
using Spring.Context;
using Spring.Context.Support;
namespace ConsoleApplication1.SpringNet
{
public class HelloWorld
{
private HelloWorld()
{
}
public static HelloWorld Create()
{
return new HelloWorld();
}
}
public class Program
{
static void Main()
{
IApplicationContext context = new XmlApplicationContext(@"Config\Spring.xml");
object o = context.GetObject("HelloWorld");
object o2 = context.GetObject("HelloWorld");
Console.WriteLine(object.ReferenceEquals(o, o2)); // output: true
}
}
}
对于这种方式,我们只需指定 "factory-method" 即可,需要注意的是所指定的方法必须是静态方法。
<?xml version="1.0" encoding="utf-8"?>
<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 >
</object>
</objects>
<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 >
</object>
</objects>
3. 实例工厂方法创建对象
修改上面的例子。在下面的代码中我们必须通过一个名为 Creator 的类才能创建 HelloWorld。
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using Spring.Core;
using Spring.Context;
using Spring.Context.Support;
namespace ConsoleApplication1.SpringNet
{
public class Creator
{
public HelloWorld Create()
{
return new HelloWorld();
}
}
public class HelloWorld
{
internal HelloWorld()
{
}
}
public class Program
{
static void Main()
{
IApplicationContext context = new XmlApplicationContext(@"Config\Spring.xml");
object o = context.GetObject("HelloWorld");
object o2 = context.GetObject("HelloWorld");
Console.WriteLine(object.ReferenceEquals(o, o2)); // output: true
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Threading;
using Spring.Core;
using Spring.Context;
using Spring.Context.Support;
namespace ConsoleApplication1.SpringNet
{
public class Creator
{
public HelloWorld Create()
{
return new HelloWorld();
}
}
public class HelloWorld
{
internal HelloWorld()
{
}
}
public class Program
{
static void Main()
{
IApplicationContext context = new XmlApplicationContext(@"Config\Spring.xml");
object o = context.GetObject("HelloWorld");
object o2 = context.GetObject("HelloWorld");
Console.WriteLine(object.ReferenceEquals(o, o2)); // output: true
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<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 />
</objects>
<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 />
</objects>
通过上面的配置文件我们知道,我们必须提供一个 Creator 的注入声明,同时要为 HelloWorld 指定创建者的 "factory-object" 和 "factory-method"。
4. 对象初始化方法
我们可以在配置文件中使用 "init-method" 指定类型构造方法以外的初始化方法。该方法会在对象构造方法之后被容器调用执行,以便我们完成一些初始化操作。
<?xml version="1.0" encoding="utf-8"?>
<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 />
</objects>
<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 />
</objects>
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using Spring.Core;
using Spring.Context;
using Spring.Context.Support;
namespace ConsoleApplication1.SpringNet
{
public class HelloWorld
{
public HelloWorld()
{
}
public void Init()
{
Console.WriteLine("Init...");
}
}
public class Program
{
static void Main()
{
IApplicationContext context = new XmlApplicationContext(@"Config\Spring.xml");
object o = context.GetObject("HelloWorld");
Console.WriteLine(o);
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Threading;
using Spring.Core;
using Spring.Context;
using Spring.Context.Support;
namespace ConsoleApplication1.SpringNet
{
public class HelloWorld
{
public HelloWorld()
{
}
public void Init()
{
Console.WriteLine("Init...");
}
}
public class Program
{
static void Main()
{
IApplicationContext context = new XmlApplicationContext(@"Config\Spring.xml");
object o = context.GetObject("HelloWorld");
Console.WriteLine(o);
}
}
}
需要注意的是对于 Singleton 方式来说,初始化只会被执行一次,因为后续对象是直接从容器中拷贝引用而已。
5. 设置对象属性
除了在配置文件中提供构造参数外,我们还可以直接为对象属性赋值。
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using Spring.Core;
using Spring.Context;
using Spring.Context.Support;
namespace ConsoleApplication1.SpringNet
{
public class HelloWorld
{
public HelloWorld()
{
}
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
public override string ToString()
{
return name;
}
}
public class Program
{
static void Main()
{
IApplicationContext context = new XmlApplicationContext(@"Config\Spring.xml");
object o = context.GetObject("HelloWorld");
Console.WriteLine(o);
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Threading;
using Spring.Core;
using Spring.Context;
using Spring.Context.Support;
namespace ConsoleApplication1.SpringNet
{
public class HelloWorld
{
public HelloWorld()
{
}
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
public override string ToString()
{
return name;
}
}
public class Program
{
static void Main()
{
IApplicationContext context = new XmlApplicationContext(@"Config\Spring.xml");
object o = context.GetObject("HelloWorld");
Console.WriteLine(o);
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<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 />
</object>
</objects>
<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 />
</object>
</objects>
6. 设置类型参数
上面的例子我们注入的数据都是基本类型,对于自定义类型我们需要做些声明。下面的例子中 HelloWorld 需要 2 个构造参数,分别是一个自定义类型和 Type。
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using Spring.Core;
using Spring.Context;
using Spring.Context.Support;
namespace ConsoleApplication1.SpringNet
{
public class MyData
{
public override string ToString()
{
return "MyData...";
}
}
public class HelloWorld
{
private MyData data;
public HelloWorld(MyData data, Type type)
{
this.data = data;
Console.WriteLine(type);
}
public override string ToString()
{
return data.ToString();
}
}
public class Program
{
static void Main()
{
IApplicationContext context = new XmlApplicationContext(@"Config\Spring.xml");
object o = context.GetObject("HelloWorld");
Console.WriteLine(o);
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Threading;
using Spring.Core;
using Spring.Context;
using Spring.Context.Support;
namespace ConsoleApplication1.SpringNet
{
public class MyData
{
public override string ToString()
{
return "MyData...";
}
}
public class HelloWorld
{
private MyData data;
public HelloWorld(MyData data, Type type)
{
this.data = data;
Console.WriteLine(type);
}
public override string ToString()
{
return data.ToString();
}
}
public class Program
{
static void Main()
{
IApplicationContext context = new XmlApplicationContext(@"Config\Spring.xml");
object o = context.GetObject("HelloWorld");
Console.WriteLine(o);
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<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 />
</objects>
<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 />
</objects>
一定要注意,注入一个对象和一个 Type 的不同之处。
[Spring.NET IoC] 之四:配置补充
1. 别名
我们为 HelloWorld 创建了一个别名 HelloWorld2,我们同样可以通过 HelloWorld2 获取对象。请注意下面的测试代码输出结果。
2. 继承
下面的例子中,我们为 HelloWorld 添加了一个 "parent" 声明,该申明表示 HelloWorld 继承 test 的配置属性,包括构造参数和属性设置,但不包括 "singleton" 等。当然继承的仅仅是配置信息,而不是类型。
3. 内联
对于下面的配置文件,我们还可以改成内联方式。
修改结果
4. 空值
注意空值(null) 和空字符串("")不同。
<?xml version="1.0" encoding="utf-8"?>
<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 />
</objects>
<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 />
</objects>
我们为 HelloWorld 创建了一个别名 HelloWorld2,我们同样可以通过 HelloWorld2 获取对象。请注意下面的测试代码输出结果。
object o = context.GetObject("HelloWorld");
object o2 = context.GetObject("HelloWorld2");
Console.WriteLine(object.ReferenceEquals(o, o2)); // output: true
object o2 = context.GetObject("HelloWorld2");
Console.WriteLine(object.ReferenceEquals(o, o2)); // output: true
2. 继承
下面的例子中,我们为 HelloWorld 添加了一个 "parent" 声明,该申明表示 HelloWorld 继承 test 的配置属性,包括构造参数和属性设置,但不包括 "singleton" 等。当然继承的仅仅是配置信息,而不是类型。
<?xml version="1.0" encoding="utf-8"?>
<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 />
</objects>
<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 />
</objects>
3. 内联
对于下面的配置文件,我们还可以改成内联方式。
<?xml version="1.0" encoding="utf-8"?>
<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 />
</objects>
<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 />
</objects>
修改结果
<?xml version="1.0" encoding="utf-8"?>
<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 />
</constructor-arg>
</object>
</objects>
<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 />
</constructor-arg>
</object>
</objects>
4. 空值
注意空值(null) 和空字符串("")不同。
<?xml version="1.0" encoding="utf-8"?>
<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 >
<null/>
</constructor-arg>
</object>
</objects>
<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 >
<null/>
</constructor-arg>
</object>
</objects>
[Spring.NET IoC] 之五:列表参数
我们可以在配置文件中向构造方法或者属性注入列表型参数,诸如 Array、ArrayList、Hashtable 等。
1. IList
在 .NET Framework 中实现 IList 的主要是 Array、ArrayList。
<?xml version="1.0" encoding="utf-8"?>
<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 >
<list>
<value>1</value>
<value>2</value>
<value>3</value>
<value>4</value>
</list>
</constructor-arg>
</object>
</objects>
<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 >
<list>
<value>1</value>
<value>2</value>
<value>3</value>
<value>4</value>
</list>
</constructor-arg>
</object>
</objects>
public class HelloWorld
{
public HelloWorld(IList list)
{
Console.WriteLine(list); // output: ArrayList
foreach (object o in list)
Console.WriteLine(o);
}
}
{
public HelloWorld(IList list)
{
Console.WriteLine(list); // output: ArrayList
foreach (object o in list)
Console.WriteLine(o);
}
}
我们会发现 Spring.NET IoC 缺省使用 ArrayList 来实现 IList 列表参数。
2. IDictionary
实现 IDictionary 的最常用类型是 Hashtable。
<?xml version="1.0" encoding="utf-8"?>
<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 />
</dictionary>
</constructor-arg>
</object>
</objects>
<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 />
</dictionary>
</constructor-arg>
</object>
</objects>
public class HelloWorld
{
public HelloWorld(IDictionary dict)
{
Console.WriteLine(dict); // output:System.Collections.Specialized.HybridDictionary
foreach (object o in dict.Keys)
{
Console.WriteLine("{0}={1}", o, dict[o]);
}
}
}
{
public HelloWorld(IDictionary dict)
{
Console.WriteLine(dict); // output:System.Collections.Specialized.HybridDictionary
foreach (object o in dict.Keys)
{
Console.WriteLine("{0}={1}", o, dict[o]);
}
}
}
看看 System.Collections.Specialized.HybridDictionary 的MSDN说明
在集合较小时,使用 ListDictionary 来实现 IDictionary,然后当集合变大时,切换到 Hashtable。
建议将该类用于字典中的元素数量未知的情况。它利用了 ListDictionary 处理小集合时性能改善的优点,同时也可灵活地切换到处理较大集合时能力比 ListDictionary 更好的 Hashtable。
如果集合的初始大小大于 ListDictionary 的最佳大小,那么集合立即存储在 Hashtable 中,以避免将元素从 ListDictionary 复制到 Hashtable 产生的系统开销。