Spring.net的Demo項目,瞭解什麼是控制反轉

Spring這個思想,已經推出不少年了。程序員

剛開始的時候,首先是在Java裏面提出,後來也推出了.net的版本。spring

 

Spring裏面最主要的就是控制反轉(IOC)和依賴注入(DI)這兩個概念。數據庫

網上不少教程都有詳細的介紹這兩個概念和相關的教程,可是至於何時會用獲得Spring,爲何要使用Spring,提到的教程很少。框架

通過研究以後,決定寫個Demo,供你們瞭解。ui

 

本人是.net程序員,因此會經過下面這個.net項目進行說明,this

開發軟件:VS2017,Framework版本:4.0spa

 

首先,介紹一下這個項目的基本信息,這是一個經過用戶的Id查找用戶信息的Demo,默認,咱們是到Sql數據庫中進行查找。.net

解決方案裏,總共有3個項目,分別是Cong.Dao,Cong.Model,ConsoleAppcode

 

其中,Model是最簡單的,裏面只有一個User類,用於表示一個用戶,有用戶的Id、Name、Age、Phone、Remark,關鍵是Remark屬性,用於區分使用Spring的先後對比。orm

 1 namespace Cong.Model  2 {  3     public class User  4  {  5         public string Id { get; set; }  6 
 7         public string Name { get; set; }  8 
 9         public int Age { get; set; } 10 
11         public string Phone { get; set; } 12 
13         public string Remark { get; set; } 14 
15         public User(string id, string name, int age, string phone, string remark) 16  { 17             this.Id = id; 18             this.Name = name; 19             this.Age = age; 20             this.Phone = phone; 21             this.Remark = remark; 22  } 23 
24         public string Hello() 25  { 26             return string.Format("我是{0},聯繫電話是{1},數據來源於:{2}。", Name, Age, Remark); 27  } 28  } 29 }

 

Cong.Dao裏有一個接口IUserDao和一個類UserSqlDao,接口是爲了擴展性,類是用於做爲數據訪問層,但這裏並非真的鏈接到數據庫,只是寫固定代碼來模擬,代碼以下:

1 namespace Cong.Dao 2 { 3     public interface IUserDao 4  { 5         User GetUserById(string id); 6  } 7 }
 1 namespace Cong.Dao  2 {  3     public class UserSqlDao : IUserDao  4  {  5         public User GetUserById(string id)  6  {  7  User ui;  8             if (id.Equals("1"))  9  { 10                 ui = new User(id, "德華", 20, "12345678912", "SQL"); 11  } 12             else
13  { 14                 ui = new User(id, "學友", 21, "98765432121", "SQL"); 15  } 16 
17             return ui; 18  } 19  } 20 }

 

ConsoleApp就是一個控制檯,咱們經過輸入用戶的Id,就能到數據庫查出用戶的信息。

 1 namespace ConsoleApp  2 {  3     class Program  4  {  5         static void Main(string[] args)  6  {  7             Console.Write("輸入用戶Id:");  8             string id = Console.ReadLine();  9  Console.WriteLine(); 10 
11  IUserDao ud; 12             ud = new UserSqlDao(); 13 
14             User user = ud.GetUserById(id); 15  Console.WriteLine(user.Hello()); 16 
17  Console.ReadKey(); 18  } 19  } 20 }

 

運行結果以下:

 

到這裏,所有的代碼結束,能夠正常運行了。

 

可是,若是從此,因爲其餘緣由,須要把數據庫變動爲Oracle,除了數據須要遷移之外,咱們的程序也要進行修改。

修改的方法比較簡單,就是新建一個UserOracleDao,一樣要繼承IUserDao,

 1 namespace Cong.Dao  2 {  3     public class UserOracleDao : IUserDao  4  {  5         public User GetUserById(string id)  6  {  7  User ui;  8             if (id.Equals("1"))  9  { 10                 ui = new User(id, "德華", 20, "12345678912", "Oracle"); 11  } 12             else
13  { 14                 ui = new User(id, "學友", 21, "98765432121", "Oracle"); 15  } 16 
17             return ui; 18  } 19  } 20 }

 

而在控制檯的代碼中,須要把new UserSqlDao() 修改成new UserOracleDao()。

可是,這裏有些問題:

一、新建一個Dao類,是必需要的;

二、須要修改主程序的代碼,而因爲這只是個Demo項目,實際的開發項目中,代碼比這個Demo的多得多,可能也會有Bll層,咱們就要修改多個類的代碼了,頗有可能會改錯,這不便於維護;

三、若是需求是,Sql和Oracle須要同時存在,使用過程當中,由用戶選擇決定,之後可能還有更多的數據庫追加,那麼咱們須要修改的代碼,就變得更多更復雜了。

 

因此,這個時候就可使用Spring了。

爲何使用Spring?

Spring能夠下降代碼的耦合度,便於擴展,便於維護。

使用Spring有什麼好處?

可讓咱們在後期維護程序時,大幅度減小修改代碼的量,下降出錯的機率。

 

直接上代碼吧。

首先,咱們仍是須要建好上面說到的UserOracleDao類。

而後,在ConsoleApp項目中,經過Nuget安裝「Spring.Core」,而且新建一個App.config,

 1 <?xml version="1.0" encoding="utf-8" ?>
 2 <configuration>
 3   
 4   <configSections>
 5     <sectionGroup name="spring">
 6       <!--跟下面Spring.Net節點配置是一一對應關係-->
 7       <section name="context" type="Spring.Context.Support.ContextHandler,Spring.Core"/>
 8       <section name="objects" type="Spring.Context.Support.DefaultSectionHandler,Spring.Core"/>
 9     </sectionGroup>
10   </configSections>
11 
12   <!--Spring.Net節點配置-->
13   <spring>
14     <!--容器配置-->
15     <context>
16       <resource uri="config://spring/objects"/>
17     </context>
18     <objects>
19       <!--objects裏面放容器的全部節點-->
20       <description>An example that demonstrates simple Ioc features.</description>
21       <!--name 必需要惟一的,type = 類的全名稱,所在的程序集-->
22       <object name="UserDao" type="Cong.Dao.UserSqlDao,Cong.Dao"></object>
23       
24     </objects>
25   </spring>
26 
27   <startup>
28     <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
29   </startup>
30   
31 </configuration>

 

控制檯的代碼修改成:

 1 namespace ConsoleApp  2 {  3     class Program  4  {  5         static void Main(string[] args)  6  {  7             Console.Write("輸入用戶Id:");  8             string id = Console.ReadLine();  9  Console.WriteLine(); 10 
11  IUserDao ud; 12 
13             //IOC
14             IApplicationContext ctx = ContextRegistry.GetContext(); 15             ud = (IUserInfoDao)ctx.GetObject("UserDao"); 16 
17             User user = ud.GetUserById(id); 18  Console.WriteLine(user.Hello()); 19 
20  Console.ReadKey(); 21  } 22  } 23 }

 

解釋一下,在配置文件中,加入了<object name="UserDao" type="Cong.Dao.UserSqlDao,Cong.Dao"></object>,定義了一個鍵值對,鍵是用UserDao,對應的是要用的類,就是UserSqlDao,而後在控制檯中,經過IOC容器,加載鍵爲UserDao的值,new一個UserSqlDao的類,這個過程當中,代碼只會以鍵爲主,沒有涉及具體的類。至於實際使用時,new哪個類,全憑配置文件來定義。

例如,若是我想換爲Oracle,就把值修改成「Cong.Dao.UserOraclelDao,Cong.Dao」

 

這就與傳統的寫法有很大的差異,傳統的寫法是經過代碼來指定用哪一個類,Spring是經過寫接口,固定的代碼,在代碼中調用配置文件中的鍵,而真正決定用哪一個類,是由配置文件來決定的。這就叫作控制反轉。

IOC容器能夠理解爲,我創建一個容器,用於new類,可是我並不關心具體有什麼類。反正當我要使用的時候,我往容器裏傳入鍵,在配置文件裏寫入鍵值對,IOC容器就能返回我要的類。

這種作法,最大的優勢就是,new的動做,都集中在配置文件中,一目瞭然,管理方便。

相似的框架還有Mybatis。

 

當咱們開發一套程序時,爲了之後的擴展性,能夠加入Spring,咱們能夠爲二次開發人員提供接口,他們就能夠本身寫擴展類,加入配置文件。

也能夠把擴展的類,所有作成選項功能,讓用戶去選擇。這個功能,對於Web項目,十分有用。

 

想下載Demo源代碼的朋友,能夠到如下地址:

https://download.csdn.net/download/cycong108/10974093

(說明:因爲Spring.net的包有23M,爲了下載方便,我已經刪除了安裝包,須要運行的朋友,請自行下載安裝,版本以下圖)

 

 

寫的內容有點亂,若有發現不足的地方,歡迎指出。

相關文章
相關標籤/搜索