[Spring.NET IoC] 之三:获取对象

依照第二篇的配置文件,我们可以初步注入我们所需的类型。本篇将记录获取对象的不同方法。

1. 构造方法创建对象

这种方式最常见,大多数时候我们都会采取此方式获取对象。如果目标对象需要提供构造参数,我们也可以在配置文件中提供。
<?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 id="HelloWorld" type="ConsoleApplication1.SpringNet.HelloWorld, Learn.CUI">
    <constructor-arg name="name" value="Tom" />
    <constructor-arg name="age" value="234" />
  </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
  {
    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

我们只需在配置文件中添加一个标记即可改变为非 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 id="HelloWorld" type="ConsoleApplication1.SpringNet.HelloWorld, Learn.CUI" singleton="false">
    <constructor-arg name="name" value="Tom" />
    <constructor-arg name="age" value="234" />
  </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
    }
  }
}

对于这种方式,我们只需指定 "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 id="HelloWorld" type="ConsoleApplication1.SpringNet.HelloWorld, Learn.CUI" factory-method="Create">
  </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
    }
  }
}
<?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 id="HelloWorld" type="ConsoleApplication1.SpringNet.HelloWorld, Learn.CUI" factory-method="Create" factory-object="Creator" />
  <object id="Creator" type="ConsoleApplication1.SpringNet.Creator, Learn.CUI" />
</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 id="HelloWorld" type="ConsoleApplication1.SpringNet.HelloWorld, Learn.CUI" init-method="Init" />
</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);
    }
  }
}

需要注意的是对于 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);
    }
  }
}
<?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 id="HelloWorld" type="ConsoleApplication1.SpringNet.HelloWorld, Learn.CUI">
    <property name="Name" value="Tom" />
  </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);
    }
  }
}
<?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 id="HelloWorld" type="ConsoleApplication1.SpringNet.HelloWorld, Learn.CUI">
    <constructor-arg name="data" ref="MyData" />
    <constructor-arg name="type" value="ConsoleApplication1.SpringNet.MyData, Learn.CUI" />
  </object>

  <object id="MyData" type="ConsoleApplication1.SpringNet.MyData, Learn.CUI" />
</objects>

一定要注意,注入一个对象和一个 Type 的不同之处。
posted @ 2008-09-30 09:43  wenanry  阅读(1645)  评论(0编辑  收藏  举报