『Spring.NET』IoC 中方法的注入

主要参考:Spring.NET

 

什么时候使用方法的注入?

…………………………………………………………

In most application scenarios, most object in the container are singletons. When a singleton object needs to collaborate with another singleton object, or a non-singleton object needs to collaborate with another non-singleton object, you typically handle the dependency by defining one object as a property of the other. A problem arrises when the object lifecycles are different. Suppose singleton object A needs to use a non-singleton (prototype) object B, perhaps on each method invocation on A. The container only creates the singleton object A once, and thus only gets one opportunity to set the properties. The container cannot provide object A with a new instance of object B every time one is needed.

A solution is to forego some inversion of control. You can make object A aware of the container by implementing the IApplicationContextAware interface, and by making a GetObject("B") call to the container ask for (a typically new) object B every time it needs it.—— Spring.NET

多数用户都会将容器中的大部分对象布署为singleton模式。当一个singleton对象需要和另一个singleton对象协作,或者一个非singleton对象需要和另一个非singleson对象协作时,Spring.NET都能很好的处理它们的依赖关系。但是,如果对象的生存周期不同,就可能会产生问题。例如,假设一个singleton对象A要使用一个非singleton(原型)对象B,A中的每个方法都会用到B的新实例。由于A是singleton对象,容器只有会创建它一次,也就是说只有一次给A的属性赋值的机会,所以不可能在每次A需要的时候都给它注入一个新的B。

有一种解决的办法有点违背控制反转原则:类A可以通过实现IObjectFactoryAware接口来获取容器的引用,并调用GetObject("B")在每次需要的时候从容器中请求一个(新的)对象B。但这并不是一个很好的解决方案,因为客户代码此时必须要和Spring.NET发生紧耦合。

通过方法注入,我们可以用更优雅的方式解决类似的问题。——@刘冬.NET

在我理解,当我们要给一个singleton的对象注入一个prototype的对象时,为了保证松耦合以及其可用性,我们就可以使用这个方法的注入。

 

 

怎么使用方法的注入?

……………………………………………………

第一类方法注入——查询方法注入

在配置文件中:

1 <!-- a stateful object deployed as a prototype (non-singleton) -->
2 <object id="command" class="Fiona.Apple.AsyncCommand, Fiona" singleton="false">
3   <!-- inject dependencies here as required -->
4 </object>
5
6 <!-- commandProcessor uses a statefulCommandHelpder -->
7 <object id="commandManager" type="Fiona.Apple.CommandManager, Fiona">
8   <lookup-method name="CreateCommand" object="command"/>
9 </object>

在具体的类中:

using System.Collections;

namespace Fiona.Apple
{
    public abstract class CommandManager
    {

        public object Process(IDictionary commandState)
        {
10             Command command = CreateCommand();
11             command.State = commandState;
12             return command.Execute();
13         }
14
15         // okay... but where is the implementation of this method?
16         protected abstract Command CreateCommand();
17     }
18 }

说明:

  1. 配置文件中,使用<lookup-method name="CreateCommand" object="command"/>声明注入的方式
  2. name是要查询的方法的名字;object是要注入的在配置文件中声明的对象id,也是注入方法的返回值类型。
  3. CreateCommand必须是抽象的,也就是说等待注入的方法必须是抽象的,含有等待注入方法的类必须是抽象的。

 

第二类方法注入——替换任意方法

在配置文件中:

1 <object id="myValueCalculator" type="Examples.MyValueCalculator, ExampleAssembly">
2   <!-- arbitrary method replacement -->
3   <replaced-method name="ComputeValue" replacer="replacementComputeValue">
4     <arg-type match="String"/>
5   </replaced-method>
6 </object>
7
8 <object id="replacementComputeValue" type="Examples.ReplacementComputeValue, ExampleAssembly"/>

在具体的类中:

1 public class MyValueCalculator {
2
3   public virtual string ComputeValue(string input) {
4     // ... some real code
5   }
6
7   // ... some other methods
8 }

/// <summary>
/// Meant to be used to override the existing ComputeValue(string)
/// implementation in MyValueCalculator.
/// </summary>
public class ReplacementComputeValue : IMethodReplacer 
{
    public object Implement(object target, MethodInfo method, object[] arguments)
    {
        // get the input value, work with it, and return a computed result...
10         string value = (string) arguments[0];
11         // compute...
12         return result;
13     }
14 }

 

说明:

  • 等待替换的方法必须是virtual方法,也就是虚方法。
  • 实现类中的IMethodReplacer是必须的。
  • public object Implement(object target, MethodInfo method, object[] arguments) 是固定的。
  • arguments是用于接收ComputeValue中传入的参数input的,如果ComputeValue有多个参数,Implement也会有对应顺序的值保存在arguments中。
  • result不是固定的,这个要根据ComputeValue来确定。


posted @ 2012-02-01 17:12  莫不逢  阅读(684)  评论(0编辑  收藏  举报