Dependecy Injection
前言
以前没怎么接触过设计模式,直到最近遇到DI,花了大把时间去找文章解读。翻阅了很多文章,很难找到一片完全符合自己的,于是总结归纳以备忘。
正文
三个重要概念:
- Dependecy Inversion Principle
一种思想,并不是Coding领域专有:“Abstractions should not depend on details; details should depend on abstractions.” - Inversion of Control
是说在Coding领域应如何应用上面的那种思想 - Dependecy Injection
实际实现。
理解一:是NEW 的一种高级用法
理解二:将底层类以类似参数的形式注入到上层类中,实现上层类控制下层类 - Dependecy Injection Container
本质上是一个工厂,负责提供向它请求的类型实例
管理应用程序中对象的生命周期
(依赖还有个原则,依赖于抽象,而不是依赖于具体实现)
上面第三点提到以类似参数的形式注入上层类,一般情况下有三种方式:
- 构造函数注入
- SETTER注入
- 接口注入
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
完全理解以上内容,足以自己去实现一个DI框架,下面我们看下asp.net core 中是如何实现的。
asp.net core中有个概念要分离开来,叫Middleware,它并不是DI内容中的东西,它只是用于构建asp.net core pipeline的组成中的功能件。
asp.net core 程序entry 文件是program.cs,然后还有个业务entry,startup.cs,DI内容就主要在这个startup.cs文件中。
startup.cs中有两个方法,ConfigureServices()和Configure()
其中和DI有关的方法是ConfigureServices()中,Configure()是和Middleware相关的方法
以下是startup类:
1 namespace webapp 2 { 3 public class Startup 4 { 5 public void ConfigureServices(IServiceCollection services) 6 { 7 services.AddCors(); 8 services.AddMvc();
//services.AddTransient<Interface,Class>();
//services.AddScoped<Interface,Class>();
//services.AddSingleton<Interface,Class>();
9 } 10 public void Configure(IApplicationBuilder app, IHostingEnvironment env) 11 { 12 app.UseStaticFiles(); 13 app.UseMvc(routes => 14 { 15 routes.MapRoute( 16 name:"default", 17 template:"{controller=Home}/{action=Index}/{id?}" 18 ); 19 }); 20 } 21 } 22 }
IServiceCollection用于管理依赖关系,实例生命周期,IServicePrivider是IOC,
(IOC容器和IserviceCollection是如何实现的具体参见github上的源码)
注册依赖方法有多种,但微软提供了几个简单的扩展方法
services.AddTransient<Interface,Class>()
services.AddScoped<Interface,Class>()
services.AddSingleton<Interface,Class>()
asp.net core 用的是构造函数注入的方法使用DI,遵循显示依赖原则(explicit dependecy),同时结合了接口编程的思想,在使用时在构造函数中注入即可
参考:
Inversion of Control Containers and the Dependency Injection pattern
ASP.NET Core 中文文档 第三章 原理(10)依赖注入