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发生紧耦合。

  通过方法注入,我们可以用更优雅的方式解决类似的问题。(摘自Spring.NET中文手册)

  一、查询方法注入

  Spring.NET可以动态覆盖对象的抽象方法或虚方法,并且可以在容器内查找已命名对象,查询方法注入就利用了这些功能。个人感觉查询方法注入类似抽象工厂,为之不同的是,可以不用写抽象的实现代码,通过配置文件动态的切换组件。

  在lookup-method节点配置name和object属性

  实现代码如下:

      <!--查询方法-->
      <object id="personDao" type="SpringNet_MethodDi.PersonDao, SpringNet_MethodDi" singleton="false"/>
      <object id="objectFactory" type="SpringNet_MethodDi.ObjectFactory, SpringNet_MethodDi">
        <lookup-method name="CreatePersonDao" object="personDao"/>
      </object>

 

LookupMethod

    //注意,可以直接在配置中定义这个类的对象
    public abstract class ObjectFactory   
    {
        //或者可以是一个虚方法    
        public abstract PersonDao CreatePersonDao();    
    }
    public class PersonDao
    {
        public void Save()
        {
            Console.WriteLine("保存数据");
        }
    }

  二、替换任意方法

  替换任意方法在项目中使用的很少,实现方法也比较复杂。至于Spring.NET为什么使用替换任意方法,我还不是很清楚,如果有知道使用场景的朋友可以给我留言。我个人认为其用途是:实现非派生类方法的重写或在IoC框架中简易的AOP拦截(这一点又不确定,以后我会写AOP方面的博客)。

  首先继承IMethodReplacer接口并实现Implement方法,object[] arguments为传入的参数。其次在replaced-method节点配置name和replacer属性,和增加arg-type节点且配置返回类型match属性

  代码如下:

      <!--替换方法-->
      <object id="userDao" type="SpringNet_MethodDi.UserDao, SpringNet_MethodDi">
        <replaced-method name="GetValue" replacer="replaceValue">
          <arg-type match="String"/>
        </replaced-method>
      </object>
      <object id="replaceValue" type="SpringNet_MethodDi.ReplaceValue, SpringNet_MethodDi"/>

 

ReplacedMethod

    public class UserDao
    {
        //虚方法
        public virtual string GetValue(string input)
        {
            return null;
        }
    }
    //实现IMethodReplacer接口
    public class ReplaceValue : IMethodReplacer
    {
        public object Implement(object target, MethodInfo method, object[] arguments)
        {
            string value = (string)arguments[0];
            return "获取到:" + value;
        }
    }

  三、事件注入

  在Spring.NET的IoC框架中,除了提供方法注入以外,还提供事件的注入。通过事件的注入,可以使架构体系的耦合降到最低。(参考 clingingboy的 Spring.NET学习笔记(3)-注册事件注入)

  在listener节点处配置event和method属性指明事件名和绑定的方法,并增加ref节点设置object属性来指明调用哪个IoC容器对象。

  实现代码:

      <!--事件注入-->
      <object id="men" type="SpringNet_MethodDi.Men, SpringNet_MethodDi">
        <listener event="OpenTheDoor" method="OpenThisDoor">
          <ref object="door"/>
        </listener>
      </object>          
      <object id="door" type="SpringNet_MethodDi.Door, SpringNet_MethodDi" />

 

Listener

    //先定义一个委托
    public delegate string OpenHandler(string arg);
    public class Door
    {
        public event OpenHandler OpenTheDoor;
        public void OnOpen(string arg)
        {
            //调用事件
            if (OpenTheDoor != null)
            {
                Console.WriteLine(OpenTheDoor(arg));
            }
        }
    }
    public class Men
    {
        public string OpenThisDoor(string arg)
        {
            return "参数是:" + arg;
        }
    }

  调用部分代码:

  Program

class Program
    {
        static void Main(string[] args)
        {
            IApplicationContext ctx = ContextRegistry.GetContext();
            Console.WriteLine("查询方法");
            ObjectFactory factory = (ObjectFactory)ctx.GetObject("objectFactory");
            factory.CreatePersonDao().Save();
            Console.WriteLine();
            Console.WriteLine("替换方法");
            UserDao dao = (UserDao)ctx.GetObject("userDao");
            Console.WriteLine(dao.GetValue("Liu Dong"));
            Console.WriteLine();
            Console.WriteLine("事件注册");
            Door door = (Door)ctx.GetObject("door");
            door.OnOpen("Opening!");
            Console.WriteLine();
            Console.ReadLine();
        }
    }

 

  输入效果:

Spring.NET教程(十)——方法的注入(基础篇) Level 200

 博客原文:http://www.cnblogs.com/GoodHelper/archive/2009/11/11/SpringNet_Method.html

转载于:https://www.cnblogs.com/wangyhua/p/IOC8.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程通过实际项目融入常用开发技术架构,讲授风格独特,提供详细上课日志及答疑,赠送配套的项目架构源码注释详细清晰且表达通俗,均能直接在实际项目中应用,正真的物超所值,价格实惠任务作业:综合运用《C#/.Net企业级系统架构设计实战精讲教程》课程所学知识技能设计一个学生成绩管理系统的架构。要求:1.系统基于MVC的三层架构,各层单独建不同的解决方案文件夹。2.采用Model First开发方式,设计架构时只需要设计学生表(TbStudent)和课程表(TbCourse)。学生表必须有的字段是ID、stuName、age;课程表必须有的字段是ID、courseName、content。3.数据访问层采用Entity Framework或NHibernate来实现,必须封装对上述表的增删改查方法。4.必须依赖接口编程,也就是必须要有数据访问层的接口层、业务逻辑层的接口层等接口层。层层之间必须减少依赖,可以通过简单工厂或抽象工厂。5.至少采用简单工厂、抽象工厂、Spring.Net等技术中的2种来减少层与层之间的依赖等。6.封装出DbSession类,让它拥有所有Dal层实例和SaveChanges方法。7.设计出数据访问层及业务逻辑层主要类的T4模板,以便实体增加时自动生成相应的类。8.表现层要设计相关的控制器和视图来验证设计的系统架构代码的正确性,必须含有验证增删改查的方法。9.开发平台一定要是Visual Studio平台,采用C#开发语言,数据库为SQL Server。10.提交整个系统架构的源文件及生成的数据库文件。(注意: 作业需写在CSDN博客中,请把作业链接贴在评论区,老师会定期逐个批改~~)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值