zoukankan      html  css  js  c++  java
  • 『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来确定。


  • 相关阅读:
    mysql-5.7 show engine innodb status 详解
    mysql-5.7 saving and restore buffer pool state 详解
    mysql-5.7 监控innodb buffer pool load 的进度 详解
    python3 functools partial 用于函数的包装器详解
    mysql-5.7 innodb change buffer 详解
    mysqlbackup 重建带有gtid特性的slave
    将python图片转为二进制文本的实例
    nginx: [error] invalid PID number "" in "/run/nginx.pid"
    ubuntu中执行定时任务crontab
    Matplotlib:mpl_toolkits.mplot3d工具包
  • 原文地址:https://www.cnblogs.com/sitemanager/p/2334887.html
Copyright © 2011-2022 走看看