前言
依赖倒置原则(DIP):一种软件架构设计的原则(抽象概念)。
控制反转(IoC):一种反转流、依赖和接口的方式(DIP的具体实现方式)。
依赖注入(DI):IoC的一种实现方式,用来反转依赖(IoC的具体实现方式)。
IoC容器:依赖注入的框架,用来映射依赖,管理对象创建和生存周期(DI框架)。
1.依赖倒置原则(DIP)
- 高层次的模块不应该依赖于低层次的横块,他们都应该依赖于抽象
- 抽象不应该依赖于具体实现,具体实现应该依赖于抽象
简单说:程序应该依赖抽象接口,而不应该依赖具体实现
DIP软件架构设计原则。仅告诉你两个模块应该如何依赖,但不告诉你如何做。IoC则是一种软件设计模式,它告诉你应该如何做
2.控制反转 (IoC)
代码语言:javascript复制 它为相互依赖的组件提供抽象,将依赖(低层模块)对象的获得交给第三方(系统)来控制**,**即依赖对象不在被依赖模块的类中直接通过new来获取
3.依赖注入(DI)
将依赖对象的创建和绑定转移到被依赖对象类的外部来实现
三种方式
1.构造函数注入( 通过构造函数初始化传递依赖 )
代码语言:javascript复制首先,定义SqlServerDal的抽象类型IDataAccess,并在IDataAccess接口中声明一个Add方法。
public interface IDataAccess
{
void Add();
}
然后在SqlServerDal类中,实现IDataAccess接口。
public class SqlServerDal:IDataAccess
{
public void Add()
{
Console.WriteLine("在数据库中添加一条订单!");
}
}
接下来,我们还需要修改Order类。
public class Order
{
private IDataAccess _ida;//定义一个私有变量保存抽象
//构造函数注入
public Order(IDataAccess ida)
{
_ida = ida;//传递依赖
}
public void Add()
{
_ida.Add();
}
}
调用
class Program
{
static void Main(string[] args)
{
SqlServerDal dal = new SqlServerDal();//在外部创建依赖对象
Order order = new Order(dal);//通过构造函数注入依赖
order.Add();
Console.Read();
}
}
从上面我们可以看出,我们将依赖对象SqlServerDal对象的创建和绑定转移到Order类外部来实现,这样就解除了SqlServerDal和Order类的耦合关系。当我们数据库换成Access数据库时,只需定义一个AccessDal类,然后外部重新绑定依赖,不需要修改Order类内部代码,则可实现Access数据库的操作。
2.属性注入( 通过属性get set来传递依赖 )
代码语言:javascript复制public class Order
{
private IDataAccess _ida;//定义一个私有变量保存抽象
//属性,接受依赖
public IDataAccess Ida
{
set { _ida = value; }
get { return _ida; }
}
public void Add()
{
_ida.Add();
}
}
class Program
{
static void Main(string[] args)
{
AccessDal dal = new AccessDal();//在外部创建依赖对象
Order order = new Order();
order.Ida = dal;//给属性赋值
order.Add();
Console.Read();
}
}
3.接口注入 (不常见)
代码语言:javascript复制首先定义一个接口:
public interface IDependent
{
void SetDependence(IDataAccess ida);//设置依赖项
}
依赖类实现这个接口:
public class Order : IDependent
{
private IDataAccess _ida;//定义一个私有变量保存抽象
//实现接口
public void SetDependence(IDataAccess ida)
{
_ida = ida;
}
public void Add()
{
_ida.Add();
}
}
控制台程序通过SetDependence方法传递依赖:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DIPTest
{
class Program
{
static void Main(string[] args)
{
AccessDal dal = new AccessDal();//在外部创建依赖对象
Order order = new Order();
order.SetDependence(dal);//传递依赖
order.Add();
Console.Read();
}
}
}
我们同样能得到上述的输出结果。
4.IoC容器
前面所有的例子中,我们都是通过手动的方式来创建依赖对象,并将引用传递给被依赖模块。比如:
代码语言:javascript复制`SqlServerDal dal = ``new` `SqlServerDal();``//在外部创建依赖对象``Order order = ``new` `Order(dal);``//通过构造函数注入依赖`
对于大型项目来说,相互依赖的组件比较多。如果还用手动的方式,自己来创建和注入依赖的话,显然效率很低,而且往往还会出现不可控的场面。正因如此,IoC容器诞生了。IoC容器实际上是一个DI框架,它能简化我们的工作量。它包含以下几个功能:
- 动态创建、注入依赖对象。
- 管理对象生命周期。
- 映射依赖关系。
目前,比较流行的Ioc容器有以下几种:
- Ninject
- Castle
- Autofac
- Unity (Unity 扩展介绍:http://www.cnblogs.com/tuyile006/p/6929796.html)
- spring.NET
版权属于:dingzhenhua
本文链接:https://cloud.tencent.com/developer/article/2019181
转载时须注明出处及本声明