zoukankan      html  css  js  c++  java
  • Spring.net的Demo项目,了解什么是控制反转

    Spring这个思想,已经推出很多年了。

    刚开始的时候,首先是在Java里面提出,后来也推出了.net的版本。

     

    Spring里面最主要的就是控制反转(IOC)和依赖注入(DI)这两个概念。

    网上很多教程都有详细的介绍这两个概念和相关的教程,但是至于什么时候会用得到Spring,为什么要使用Spring,提到的教程不多。

    经过研究之后,决定写个Demo,供大家了解。

     

    本人是.net程序员,所以会通过下面这个.net项目进行说明,

    开发软件:VS2017,Framework版本:4.0

     

    首先,介绍一下这个项目的基本信息,这是一个通过用户的Id查找用户信息的Demo,默认,我们是到Sql数据库中进行查找。

    解决方案里,总共有3个项目,分别是Cong.Dao,Cong.Model,ConsoleApp

     

    其中,Model是最简单的,里面只有一个User类,用于表示一个用户,有用户的Id、Name、Age、Phone、Remark,关键是Remark属性,用于区分使用Spring的前后对比。

     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()。

    但是,这里有些问题:

    1、新建一个Dao类,是必须要的;

    2、需要修改主程序的代码,而由于这只是个Demo项目,实际的开发项目中,代码比这个Demo的多得多,可能也会有Bll层,我们就要修改多个类的代码了,很有可能会改错,这不便于维护;

    3、如果需求是,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,为了下载方便,我已经删除了安装包,需要运行的朋友,请自行下载安装,版本如下图)

     

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

     

  • 相关阅读:
    php----爬虫(爬取豆瓣演员信息,搜索页)遇到的问题
    python-写爬虫时遇到的问题 TimeoutError: [WinError 10060]
    聚沙成塔
    买手机,继续纠结中
    问题不绕弯,死磕
    死磕,死磕死磕
    学而不践则罔
    越是忙的时候,兴趣越多
    周末小总结
    幸福和需求
  • 原文地址:https://www.cnblogs.com/chenyucong/p/10429766.html
Copyright © 2011-2022 走看看