posted at 2017.5.2 20:27 by 风信子
依赖注入怎么理解?
举个例子,组件A中有类ClassA,组件B中有接口IB和其对应的实现类B1和B2。
那么,现在ClassA需要利用IB接口来做一些事情,例如:
public class ClassA {
public void DoSomething() {
IB b =???
b.DoWork();
}
}
现在的问题来了,IB b = 中这三个?要写什么代码?是要写成 IB b = new B1(),还是要写成IB b = new B2() ?
不管是哪一种,都会让ClassA强依赖于IB的实现。
在上面这种方案中,ClassA通过new一个B1或B2来实现对IB的依赖的获取,换句话说,ClassA在主动获取依赖。
这样的设计会让ClassA很难扩展,那我们要改良设计:使用依赖注入。上面说到了,问题出在new这里,也就是依赖是Class去主动获取的,那我们就要解决这个问题:不要去主动获取对IB的依赖(通过new),而让这个依赖从ClassA的外面“注入”进来。注入有多种方式,比较常用的一种是通过构造函数注入,那么,我们要把ClassA改成:
public class ClassA {
private IB b;
public ClassA(IB b) {
this.b = b;
}
public DoSomething() {
this.b.DoWork();
}
}
可以看到,通过把IB这个依赖从构造函数中“注”进来后,ClassA就不依赖IB的实现了。还可以发现,这个重构过程中,我们是把"ClassA主
动获取对IB的依赖”变成“把对IB的依赖从外部注入到ClassA中”,依赖的方向反转了,所以,依赖注入又称“控制反转”。
下面是依赖注入的三种实例:
1. Constructor Injection
public class Boy {
private IDog smallDog;
public Boy(IDog smallDog) {
this.smallDog = smallDog;
}
}
public interface IDog {
//method
}
2. Setter Injection
public class Boy {
private IDog smallDog;
public IDog SmallDog {
get {
return smallDog;
}
set {
smallDog = value;
}
}
}
public interface IDog {
//method
}
3. Interface Injection
public class Boy : IDogMgr {
private IDog smallDog;
public void InjectDog(IDog smallDog) {
this.smallDog = smallDog;
}
}
public interface IDog {
//method
}
public interface IDogMgr {
void InjectDog(IDog smallDog);
}
a78df34e-2741-494d-ac41-ec34b41a0ff5|0|.0|96d5b379-7e1d-4dac-a6ba-1e50db561b04
Tags: 依赖注入, 接口
IT技术