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,为了下载方便,我已经删除了安装包,须要运行的朋友,请自行下载安装,版本以下图)

 

 

写的内容有点乱,若有发现不足的地方,欢迎指出。

相关文章
相关标签/搜索