.net framework 的控制反转和依赖注入
我们有一个类A,一个类B,A中的方法需要调用B中的方法,我们称为A依赖于B,常见的写法如下:
public class A { private B _b; public A() { _b = new B(); } public string MethodA() { return _b.MethodB(); } } public class B { public string MethodB() { return "Do MethodB"; } }
调用A中的方法
internal class Program { static void Main(string[] args) { A _a = new A(); Console.WriteLine(_a.MethodA()); } }
根据依赖倒置原则,A作为高级模块,应该不依赖与B这个低级模块
依赖倒置原则
1.高级模块不应该依赖于低级模块,两者都应该依赖抽象;
2.抽象不应该依赖于细节,细节应该依赖于抽象。
因此我们加入B的抽象类,修改为
public class A { public string MethodA(IB b) { return b.MethodB(); } } public interface IB { string MethodB(); } public class B : IB { public string MethodB() { return "Do MethodB"; } }
这样编译时A依赖于抽象的IB,但是调用A的方法时,还需要先准备好B的实例。
static void Main(string[] args) { A _a = new A(); B _b = new B(); Console.WriteLine(_a.MethodA(_b)); }
因为在面向对象编程中,执行代码需要先实例化对象,再调用方法。
这里引入了一个新概念,控制反转
控制反转
有一个独立的框架,它可以获得接口IB合适的实现类B,并主动创建这个类的实例,再赋值给A的一个字段_b,也就是说A中不需要去主动创建B相关的实例,只需要声明,B的实例由这个外部框架来负责创建并提供给A。
修改A
public class A { private IB _b; public A(IB b) { _b = b; } public string MethodA() { return _b.MethodB(); } }
调用方式
static void Main(string[] args) { IB _b = new B(); A _a = new A(_b); Console.WriteLine(_a.MethodA()); }
首先 A不再依赖于B,而是依赖于抽象,然后调用A的时候,也不再需要B的实例,而是抽象接口IB的实现对象。
控制反转是一种设计原则,可以用来减少代码的耦合度。而依赖注入是它的一种实现方式。