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
在相應的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
相應的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
關於集合類型,經常使用的包括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 +" 性別:"+ item.Sex); } //輸出List<string> string output=string.Empty; foreach (var item in p.WeekWorkDay) { output += item + " "; } Response.Write("<br/> 每週在" + output + "工做"); output = string.Empty; //輸出IList foreach (var item in p.Hobbys) { output += item + " "; } Response.Write("<br/> 愛好爲" + 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>
方法注入的目的,是爲了解決非單例對象的方法調用。情景爲單例對象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