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

 

源碼下載

相關文章
相關標籤/搜索