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

     

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

     

  • 相关阅读:
    关于js计算非等宽字体宽度的方法
    [NodeJs系列]聊一聊BOM
    Vue.js路由管理器 Vue Router
    vue 实践技巧合集
    微任务、宏任务与Event-Loop
    事件循环(EventLoop)的学习总结
    Cookie、Session和LocalStorage
    MySQL 树形结构 根据指定节点 获取其所在全路径节点序列
    MySQL 树形结构 根据指定节点 获取其所有父节点序列
    MySQL 创建函数报错 This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators
  • 原文地址:https://www.cnblogs.com/chenyucong/p/10429766.html
Copyright © 2011-2022 走看看