MVC进阶之路:依赖注入(Di)和Ninject

0X1 什么是依赖注入

  依赖注入(Dependency Injection),是这样一个过程:某客户类只依赖于服务类的一个接口,而不依赖于具体服务类,所以客户类只定义一个注入点。在程序运行过程中,客户类不直接实例化具体服务类实例,而是客户类的运行上下文环境或专门组件负责实例化服务类,然后将其注入到客户类中,保证客户类的正常运行。

                                                      图1

  如图1所示,数据库操作类DataManager中依赖的IDataBase的接口,而不是以来IDataBase的具体实现类,这样的好处是可以让我们的程序具有扩展性:无论我们要使用SqlServer当我们的数据库操作类还是用Mysql,我们需要改动的地方都很少。

0X2 一个Demo理解Di

  我们创建一个控制台程序,并按照图1中所标识的关系创建四个类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class DataManager
    {
        private IDataBase _database;
        public DataManager(IDataBase database)
        {
            this._database = database;
        }
 
        public void Add()
        {
            _database.Add();
        }
 
        public void Delete()
        {
            _database.Delete();
        }
 
        public void Update()
        {
            _database.Update();
        }
 
        public void Select()
        {
            _database.Select();
        }
    }

IDataBase接口

1
2
3
4
5
6
7
8
public interface IDataBase
    {
        string DbName { get; }
        void Select();
        void Update();
        void Delete();
        void Add();
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class SqlServer : IDataBase
    {
        public string DbName
        {
            get
            {
                return "SqlServer";
            }
        }
 
        public void Add()
        {
            Console.WriteLine("Add in " + DbName);
        }
 
        public void Delete()
        {
            Console.WriteLine("Delete in " + DbName);
        }
 
        public void Select()
        {
            Console.WriteLine("Select in " + DbName);
        }
 
        public void Update()
        {
            Console.WriteLine("Update in " + DbName);
        }
    }

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public string DbName
        {
            get
            {
                return "Mysql";
            }
        }
 
        public void Add()
        {
            Console.WriteLine("Add in " + DbName);
        }
 
        public void Delete()
        {
            Console.WriteLine("Delete in " + DbName);
        }
 
        public void Select()
        {
            Console.WriteLine("Select in " + DbName);
        }
 
        public void Update()
        {
            Console.WriteLine("Update in " + DbName);
        }

如果我们要用Sqlserver作为数据库实现类的话,传统写法我们要New Sqlserver,如下图:

项目早期使用的是Sqlserver数据库没问题,后来BOSS忽然要改成Mysql数据库,你心里面一想,没问题啊,无非就是把New后面的Sqlserver换成Mysql嘛,简单。于是你就开始改,越改越不对劲,已经你已经发现当前项目已经有好几十个地方用到New Sqlserver(),而剩余的数量往往还是未知的。这个时候你就在想,有没有方法可以让我只需要改一个地方其他地方不用动就可以呢?答案是肯定的,目前这种方法实现有很多种,最简单的无非就是工厂模式。但是,今天,我们不用工厂,我们将使用Ninject来实现这种功能。

0X3 Ninject的使用

  Ninject是一个IOC容器,用来解决程序中组件的耦合问题,它的目的在于做到最少配置。其他的的IOC工具过于依赖配置文件,需要使用assembly-qualified名称来进行定义,庸长且复杂常常因为打错字而破坏程序。这些是他的优点,也是为什么要选择它。

  

安装Ninject

  打开Nuget程序包管理控制台输入“Install-Package Ninject”即可安装Ninject。

  

Ninject使用步骤

  我们一般会在程序启动的入口来创建Ninject的对象负责类型的注册。

1  static void Main(string[] args)
2 {
3 //实例化Ninject对象
4 IKernel Kerner = new StandardKernel();
5 }

  使用Ninject对象分两个步骤,第一步是把接口对象或者说被依赖的对象(IDataBase)绑定到Ninject中,然后在为其绑定对应的实例类型(如果要使用SqlServer则就绑定SqlServer)。

 //实例化Ninject对象
IKernel Kerner = new StandardKernel();
//绑定对象
Kerner.Bind<IDataBase>().To<SqlServer>();

  第二步则是通过Ninject的Get方法获取IDataBase的实现类

 var Db = Kerner.Get<IDataBase>(); //由于上面IDataBase绑定的是SqlServer类型,所以这里获取的类型是SqlServer

  上面的代码大家可能体会不到使用Ninject的好处,也没有体会到依赖注入的奥妙所在。依赖注入大致分为三类:接口注入,函数注入,属性注入。我们来通过一个例子来演示属性注入。

  我们增加一个IShowDBInfo的接口类,其有一个Show方法。然后添加一个Show类实现IShowDBInfo接口:

 public class Show1 : IShowDBInfo
{
public void Show()
{
Console.WriteLine(this.GetType().FullName);
}
}

我们给DataManager添加一个IShowDBInfo属性并增加一个Show()方法:

 public class DataManager
{
private IDataBase _database;
private IShowDBInfo _showDbInfo;
public DataManager(IDataBase database, IShowDBInfo ishowdbinfo)
{
this._database = database;
_showDbInfo = ishowdbinfo;
}
//省略Add,Updata,Delete,Select方法
public void Show()
{
_showDbInfo.Show();
}
}

  在应用程序启动的时候注册IShow类和注册DataManager类并启动程序:

 static void Main(string[] args)
{
//实例化Ninject对象
IKernel Kerner = new StandardKernel();
//绑定对象
Kerner.Bind<IDataBase>().To<SqlServer>();
Kerner.Bind<IShowDBInfo>().To<Show1>();
Kerner.Bind<DataManager>().ToSelf();
var dataManager=Kerner.Get<DataManager>();
dataManager.Show();
Console.Read();
}

  从上代码以及运行结果来看,我们只需要在向Ninject实例里面注册对象,然后在其他类中使用的时候我们只需要定义接口就可以了,并不需要实例化对象。这样做的话可以使我们和其他层进行松耦合。

MVC进阶之路:依赖注入(Di)和Ninject的更多相关文章

  1. ASP.NET MVC进阶之路:依赖注入(Di)和Ninject

    0X1 什么是依赖注入 依赖注入(Dependency Injection),是这样一个过程:某客户类只依赖于服务类的一个接口,而不依赖于具体服务类,所以客户类只定义一个注入点.在程序运行过程中,客户 ...

  2. 依赖注入(DI)和Ninject

    [ASP.NET MVC 小牛之路]04 - 依赖注入(DI)和Ninject 本文目录: 1.为什么需要依赖注入 2.什么是依赖注入 3.使用NuGet安装库 4.使用Ninject的一般步骤 5. ...

  3. 依赖注入(DI)和Ninject,Ninject

    我们所需要的是,在一个类内部,不通过创建对象的实例而能够获得某个实现了公开接口的对象的引用.这种“需要”,就称为DI(依赖注入,Dependency Injection),和所谓的IoC(控制反转,I ...

  4. 什么是IOC和什么是AOP,依赖注入(DI)和Ninject,Ninject

    我们所需要的是,在一个类内部,不通过创建对象的实例而能够获得某个实现了公开接口的对象的引用.这种“需要”,就称为DI(依赖注入,Dependency Injection),和所谓的IoC(控制反转,I ...

  5. [ASP.NET MVC 小牛之路]04 - 依赖注入(DI)和Ninject

    本人博客已转移至:http://www.exblr.com/liam  为什么需要依赖注入 在[ASP.NET MVC 小牛之路]系列的理解MVC模式文章中,我们提到MVC的一个重要特征是关注点分离( ...

  6. ADO.NET .net core2.0添加json文件并转化成类注入控制器使用 简单了解 iTextSharp实现HTML to PDF ASP.NET MVC 中 Autofac依赖注入DI 控制反转IOC 了解一下 C# AutoMapper 了解一下

    ADO.NET   一.ADO.NET概要 ADO.NET是.NET框架中的重要组件,主要用于完成C#应用程序访问数据库 二.ADO.NET的组成 ①System.Data  → DataTable, ...

  7. ASP.NET MVC 中 Autofac依赖注入DI 控制反转IOC 了解一下

    先简单了解一这个几个 名词的意思. 控制反转(IOC) 依赖注入(DI) 并不是某种技术. 而是一种思想.一种面向对象编程法则 什么是控制反转(IOC)?  什么是依赖注入(DI) 可以点击下面链接 ...

  8. [Android]使用Dagger 2依赖注入 - DI介绍(翻译)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5092083.html 使用Dagger 2依赖注入 - DI介 ...

  9. 浅析“依赖注入(DI)/控制反转(IOC)”的实现思路

    开始学习Spring的时候,对依赖注入(DI)——也叫控制反转(IOC)—— 的理解不是很深刻.随着学习的深入,也逐渐有了自己的认识,在此记录,也希望能帮助其他入门同学更深入地理解Spring.本文不 ...

随机推荐

  1. SVN导出增量包的方法

    此方法是在svn1.7版本基础上进行的操作,其他版本没有验证 第一步.点击右键,选择“TortoiseSVN–> Show log”. 进入日志页面,如下图所示: 第二步.选择版本区间,右键选择 ...

  2. Netty4.X 学习(一)

    Server: import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.net ...

  3. OpenCV学习(1) OpenCV的安装

    前沿 准备了好几天,终于开始了,不管怎样,接下来的这个月一定把这本书很好的啃下来.当然OpenCV可以在很多的IDE下安装与配置,我这里就只在VS2010和VC6.0下安装配置了,当然这篇博文主要讲在 ...

  4. meta的属性详解

    引言 您的个人网站即使做得再精彩,在“浩瀚如海”的网络空间中,也如一叶扁舟不易为人发现,如何推广个人网站,人们首先想到的方法无外乎以下几种: ● 在搜索引擎中登录自己的个人网站 ● 在知名网站加入你个 ...

  5. 关于Thinkphp3.2版本的分页问题

    最近公司官网改版,需要把旧的thinkphp版本换到现在最新的3.2去,因此,就开展了一系列的升级工作..在修改命名空间的同时,发现Page分页类能正常运行了,但是分页的链接却是错误的,例如在Admi ...

  6. C# 常用函数和方法集

    1.DateTime 数字型  System.DateTime currentTime=new System.DateTime(); 1.1 取当前年月日时分秒 currentTime=System. ...

  7. PC/SC

    简介 PC/SC规范由微软公司与世界其它著名的智能卡厂商组成的PC/SC工作组提出的.PC/SC规范是一个基于WINDOWS平台的一个标准用户接口(API),提供了一个从个人电脑(Personal C ...

  8. 最近招两个兼职的活(PHP和JSP)

    我这里的活,都是兼职写作的,是两本入门教程, 一本是PHP+Nginx 一本是JSP+Servlet. 都是入门教程,有署名有稿酬,有兴趣的可以联系 QQ:837652732  验证:PHP或Java ...

  9. NOI2014 Day1

    NOI2014 Day1 起床困难综合症 题目描述:给出\(n\)个操作,每个操作包含一种运算\((XOR.OR.AND)\)和一个数,已知一开始的数字为\([0, m]\),问经过\(n\)次操作后 ...

  10. poj2017简单题

    #include <stdio.h> #include <stdlib.h> int main() { int n,i; while(scanf("%d", ...