DIP 依赖反转原则 Dependency Inversion Principle ——项目结构 依赖反转原则DIP 与使用了Repository模式的asp.net core项目结构

 

DIP 依赖反转原则 Dependency Inversion Principle 的定义如下:

高级别的模块不应该依赖于低级别的模块, 他们都应该依赖于抽象.

假设Controller依赖于Repository的实例/实现, 而不是interface:

DIP 依赖反转原则 Dependency Inversion Principle ——项目结构
依赖反转原则DIP 与使用了Repository模式的asp.net core项目结构

这个例子里面Controller是高级别模块, Repository是低级别模块.

但是根据定义: 高级别的模块不应该依赖于低级别的模块, 他们都应该依赖于抽象. 那么如何解决这个问题呢?

那就是 从Repository中提炼出一个interface, 叫做IRepository, 它就是个抽象:

DIP 依赖反转原则 Dependency Inversion Principle ——项目结构
依赖反转原则DIP 与使用了Repository模式的asp.net core项目结构

这样一来, Controller依赖于IRepository, 所以高级别模块不依赖于低级别模块, 他们现在都依赖于抽象了.

那么这么做有什么好处? 为什么要使用DIP原则?

答案就是: 减少变化带来的影响.

看第一张图:

DIP 依赖反转原则 Dependency Inversion Principle ——项目结构
依赖反转原则DIP 与使用了Repository模式的asp.net core项目结构

就从一个方面来说, 如果Repository被重新编译了, 那么Controller肯定需要重新编译, 也就是所有依赖于Repository的类都会被重新编译.

而使用DIP原则之后:

DIP 依赖反转原则 Dependency Inversion Principle ——项目结构
依赖反转原则DIP 与使用了Repository模式的asp.net core项目结构

我们可以在Repository里面做出很多更改, 但是这些变化都不会影响到Controller, 因为Controller并不是依赖于这个实现.

只要IRepository这个interface或者叫Contract合约不发生变化, Controller就不会被影响到. 这也就可能会较少对整个项目的影响.

DIP 依赖反转原则 Dependency Inversion Principle ——项目结构
依赖反转原则DIP 与使用了Repository模式的asp.net core项目结构

Interface 代表的是 "是什么样的", 而实现代表的是 "如何去实现".

Interface一旦完成后是很少改变的.

针对使用Repository+UnitOfWork模式的asp.net core的项目结构, 少许码友可能会有一点错误的理解, 可能会把asp.net core项目的结构这样划分:

DIP 依赖反转原则 Dependency Inversion Principle ——项目结构
依赖反转原则DIP 与使用了Repository模式的asp.net core项目结构

这样一来, 其实就是这样的:

DIP 依赖反转原则 Dependency Inversion Principle ——项目结构
依赖反转原则DIP 与使用了Repository模式的asp.net core项目结构

高级别的包/模块依赖于低级别的包/模块.

也就违反了DIP原则, 所以如果想按原则执行, 就需要引进一个新的模块:

DIP 依赖反转原则 Dependency Inversion Principle ——项目结构
依赖反转原则DIP 与使用了Repository模式的asp.net core项目结构

把所有的抽象相关的类都放在Core里面.

这样就满足了DIP原则.

asp.net core的项目结构大致应该是这个思路:

DIP 依赖反转原则 Dependency Inversion Principle ——项目结构
依赖反转原则DIP 与使用了Repository模式的asp.net core项目结构

由于Models是整个项目的核心内容, 所以也放在了Core里面.

当然也可以分成多个项目去实现DIP, 但是不一定按多个项目分开了就一定实现了DIP, 还是要看他们之间的依赖关系.

DIP 依赖反转原则 Dependency Inversion Principle 的定义如下:

高级别的模块不应该依赖于低级别的模块, 他们都应该依赖于抽象.

假设Controller依赖于Repository的实例/实现, 而不是interface:

DIP 依赖反转原则 Dependency Inversion Principle ——项目结构
依赖反转原则DIP 与使用了Repository模式的asp.net core项目结构

这个例子里面Controller是高级别模块, Repository是低级别模块.

但是根据定义: 高级别的模块不应该依赖于低级别的模块, 他们都应该依赖于抽象. 那么如何解决这个问题呢?

那就是 从Repository中提炼出一个interface, 叫做IRepository, 它就是个抽象:

DIP 依赖反转原则 Dependency Inversion Principle ——项目结构
依赖反转原则DIP 与使用了Repository模式的asp.net core项目结构

这样一来, Controller依赖于IRepository, 所以高级别模块不依赖于低级别模块, 他们现在都依赖于抽象了.

那么这么做有什么好处? 为什么要使用DIP原则?

答案就是: 减少变化带来的影响.

看第一张图:

DIP 依赖反转原则 Dependency Inversion Principle ——项目结构
依赖反转原则DIP 与使用了Repository模式的asp.net core项目结构

就从一个方面来说, 如果Repository被重新编译了, 那么Controller肯定需要重新编译, 也就是所有依赖于Repository的类都会被重新编译.

而使用DIP原则之后:

DIP 依赖反转原则 Dependency Inversion Principle ——项目结构
依赖反转原则DIP 与使用了Repository模式的asp.net core项目结构

我们可以在Repository里面做出很多更改, 但是这些变化都不会影响到Controller, 因为Controller并不是依赖于这个实现.

只要IRepository这个interface或者叫Contract合约不发生变化, Controller就不会被影响到. 这也就可能会较少对整个项目的影响.

DIP 依赖反转原则 Dependency Inversion Principle ——项目结构
依赖反转原则DIP 与使用了Repository模式的asp.net core项目结构

Interface 代表的是 "是什么样的", 而实现代表的是 "如何去实现".

Interface一旦完成后是很少改变的.

针对使用Repository+UnitOfWork模式的asp.net core的项目结构, 少许码友可能会有一点错误的理解, 可能会把asp.net core项目的结构这样划分:

DIP 依赖反转原则 Dependency Inversion Principle ——项目结构
依赖反转原则DIP 与使用了Repository模式的asp.net core项目结构

这样一来, 其实就是这样的:

DIP 依赖反转原则 Dependency Inversion Principle ——项目结构
依赖反转原则DIP 与使用了Repository模式的asp.net core项目结构

高级别的包/模块依赖于低级别的包/模块.

也就违反了DIP原则, 所以如果想按原则执行, 就需要引进一个新的模块:

DIP 依赖反转原则 Dependency Inversion Principle ——项目结构
依赖反转原则DIP 与使用了Repository模式的asp.net core项目结构

把所有的抽象相关的类都放在Core里面.

这样就满足了DIP原则.

asp.net core的项目结构大致应该是这个思路:

DIP 依赖反转原则 Dependency Inversion Principle ——项目结构
依赖反转原则DIP 与使用了Repository模式的asp.net core项目结构

由于Models是整个项目的核心内容, 所以也放在了Core里面.

当然也可以分成多个项目去实现DIP, 但是不一定按多个项目分开了就一定实现了DIP, 还是要看他们之间的依赖关系.