Spring.Net---四、IoC/DI注入方式

 spring.net里实现了控制反转IOC(Inversion of control),也即依赖注入DI(Dependency Injection),以达到解耦的目的,实现模块的组件化。程序在调用spring容器的时候,会自动根据配置文件(能够本身命名xml文件,不必定是web.config或app.config)的配置,给你实例化好对象供你调用。这些实例化对象,是基于单例模式的,固然能够在配置文件里修改单例模式singleton为false,这样每次生成的都是在内存中开辟的新的对象。另外也能够在配置文件里设置lazy-init(延迟加载)为true,这样就是只有对象被调用的时候 GetObject(“对象名"),才会实例化对象。php

    spring.net的依赖注入,支持属性注入,构造器注入,集合注入,方法注入。示例以下:html

1、属性注入

    在相应的xml文件中配置以下:web

复制代码
<objects>
  <object id="compute" type="Service.Implement.Compute,Service"></object>
  <object id="modernPerson" type="Service.Implement.ModernPerson,Service">
     <!--属性注入 Tool对象由compute类注入实现-->
    <property name="Tool" ref="compute"></property>
  </object>
</objects>
复制代码

   其中modernPerson的结构以下:spring

复制代码
public  class ModernPerson:IPerson
    {
       public ITool Tool { get; set; }
       public string Work()
       {
           string str= Tool.UseTool();
           return "现代工人: "+str;
       }
    }
复制代码

在页面中调用方法为:app

IApplicationContext ctx = ContextRegistry.GetContext();
            //属性注入 moderPerson的work方法会调用Tool对象的UseTool方法,Compute类实现接口对象Tool
            Service.Implement.ModernPerson mp = ctx.GetObject("modernPerson") as Service.Implement.ModernPerson;
            Response.Write("<br/>"+mp.Work());

页面输出结果以下:ide

现代工人: 使用电脑办公:Compute
2、构造器注入

   相应的xml配置文件以下:组件化

<object id="personDao" type="Dao.PersonDao,Dao">
    <!--构造器注入 ref为指定的对象 ,若为值类型,则为value-->
    <constructor-arg name="per" ref="person"></constructor-arg>
    <constructor-arg name="remark" value="welcome"></constructor-arg>
  </object>

页面调用方法以下:spa

复制代码
//构造器注入
        void   ConstructorInjection()
        {
            IApplicationContext ctx = ContextRegistry.GetContext();
            PersonDao p = ctx.GetObject("PersonDao") as PersonDao;
            Response.Write("<br/>"+ p.ToString());
        }
复制代码

其中personDao重写了tostring方法,以验证是否读取到构造器中的数据,personDao内部代码以下:.net

复制代码
private Person _Person;
        private string _Remark;

        public PersonDao(Person per,string remark)
        {
            _Person = per;
            _Remark = remark;
        }
        public override string ToString()
        {
            return _Remark + "用户名:" + _Person.Name + " 性别:" + _Person.Sex;
        }
复制代码

页面输入结果以下:code

welcome用户名:flowbywind 性别:Boy
3、集合类型的注入

关于集合类型,经常使用的包括List和Dictionary等,下面一一介绍

a)IList类型

使用<list>元素做为IList的标签,element-type属性为泛型的类型,如Int,命名空间.类名,string等;

value为集合中元素的值;

<ref/>表示关联的对象,ref的object属性为关联对象的id或name;

集合也能够为空,用<null/>元素做为标记,此时不声明list元素。

如此时person对象的成员以下:

public IList<Person> Persons { get; set; }
        public IList Hobbys;
        public IList<string> WeekWorkDay;

其在xml中的配置以下:

复制代码
<property name="Persons">
      <list element-type="Domain.Person,Domain">
        <ref object="person"></ref>
      </list>
    </property>
    <property name="WeekWorkDay">
      <list element-type="string">
        <value>MonDay</value>
        <value>Tuesday</value>
        <value>Wednesday</value>
        <value>Thursday</value>
        <value>Friday</value>
      </list>
    </property>
    <property name="Hobbys">
      <list>
        <value>Reading</value>
        <value>Running</value>
      </list>
    </property>
    <!--空集合属性-->
    <!--<property name="BestFriends">
      <null/>
    </property>-->
复制代码

调用代码为:

复制代码
//List集合注入
        void GenericInjection()
        {
            IApplicationContext ctx = ContextRegistry.GetContext();
            PersonDao p = ctx.GetObject("PersonDao") as PersonDao;
            //输出list<Person>对象
            foreach (Person item in p.Persons)
            {
                Response.Write("<br/>采访人:" + item.Name +" &nbsp;性别:"+ item.Sex);
            }
            //输出List<string>
            string output=string.Empty;
            foreach (var item in p.WeekWorkDay)
            {
                output += item + " &nbsp;";
            }
            Response.Write("<br/>&nbsp;&nbsp;每周在" + output + "工做");
            output = string.Empty;
            //输出IList
            foreach (var item in p.Hobbys)
            {
                output += item + "&nbsp;";
            }
            Response.Write("<br/>&nbsp;&nbsp;爱好为" + output);
        }
复制代码

最后页面输出结果为:

采访人:flowbywind  性别:Boy
  每周在MonDay  Tuesday  Wednesday  Thursday  Friday  工做
  爱好为Reading Running

b)IDictionary类型

使用<dictionary/>表示IDictionary集合,其中key-type和value-type属性分别为Dict的键值对象类型;

使用<entry>用来表示dict集合的元素,key和value属性为元素的键值队,value-ref为关联的元素

<property  name="DicGrade">
      <dictionary  key-type="string" value-type="object" >
        <entry key="2012" value="最佳懒人将"></entry>
        <entry key="2013" value-ref="person"></entry>
      </dictionary>
    </property>
4、方法注入

方法注入的目的,是为了解决非单例对象的方法调用。情景为单例对象A,引用了非单例对象B,B此时可能已经注销,但A被生成一次后,没法再次生成,当A想调用B的方法时,就只能从新注入B。A能够经过实现IObjectFactoryAware来获取容器的引用,并经过调用GetObject(“B”)来生成一个新的B对象,但这样作违反了控制反转原则,方法注入此时即是一个比较优雅的解决方案。示例以下:

xml中代码以下:

<object id="objectFactory" type="Dao.ObjectFactory,Dao">
    <!--注入查找方法-->
    <lookup-method name="CreatePersonDao" object="personDao"></lookup-method>
  </object>

其中CreatePersonDao方法是抽象类ObjectFactory的抽象方法,返回PersonDao实例,继而调用personDao里的方法;

相应页面调用的方法为:

Response.Write("<br/>查询方法:");
            IApplicationContext ctx = ContextRegistry.GetContext();
            ObjectFactory factory = ctx.GetObject("objectFactory") as ObjectFactory;
            Response.Write("<br/>"+factory.CreatePersonDao().InjectionFunc());

除了查找方法外,还有替换方法和事件注入,源码中有相应实例;

参考资料:http://tech.ddvip.com/2009-11/1258094512138413_2.html

http://tech.ddvip.com/search.php?key=Spring.NET%E6%95%99%E7%A8%8B

 

源码下载

相关文章
相关标签/搜索