如果类A中有类B的实例,则称类A对类B有一个依赖
现要将一条订单添加到数据库中,需要如下代码,则Order类对SqlServerDal类有一个依赖
public class Order
{
SqlServerDal sqlServerdal;
public Order
{
sqlServerdal=new SqlServerDal();
}
}
仔细观察代码会发现问题:
1.如果以后要换一种数据库去存(或是说用不同的数据库去存订单)那将是一件很困难的事,因为数据库的初始化被写死在了Order类里,只能由SqlServerDal来去存信息,可扩展性不好;
2.如果SqlServerDal的生成方式改变了,数据库要加名称参数来加以区分了,用new SqlServerDal(string name)初始化数据库,则需要改Order代码,显然不符合开闭原则;
3.如果new SqlServerDal()的过程非常缓慢,单测时我们要用已经初始化好的SqlServerDal对象Mock掉这个过程也很困难
参数会使代码更灵活,如果把SqlServerDal类作为参数传入Order是不是就解决了上面问题
public class Order
{
SqlServerDal sqlServerDal;
public Order(SqlServerDal sqlServerDal)
{
this.sqlServerDal=sqlServerdal;
}
}
将Order类所依赖的SqlServerDal类作为一个参数传入Order中,在调用Order的构造方法之前就已经初始化好了sqlServerDal对象,这种非自己主动初始化依赖的类,而是通过将依赖作为参数传入的方式就是依赖注入。
依赖注入共有三种:刚刚说的是以构造函数的形式注入,还有属性、接口方式注入。三种注入的代码实例详见构造函数注入、属性注入、接口注入。
上面代码看似是降低了类的耦合,但实际上是将耦合的问题抛给了外部,它们的关系还在,只是位置变了,客户端调用的时候还需要实例化这些代码。这就需要IoC容器来解决这些问题了,把注入交给容器去做,从而降低对象间的耦合。
对于IoC容器的详解就去看大神们的博客吧,我目前了解的就这么多。