做网站端口映射,wordpress首页很慢,王烨飞,南坪做网站IOC: Inversion Of Control 控制反转DI: Dependency Injection 依赖注入1.控制反转 Inversion Of Control 的前世今生1.1 IOC理论产生的背景讨论控制反转之前#xff0c;先看看软件系统提出控制反转的前世今生。一个完整精密的软件系统#xff0c;组件之间就像齿轮… IOC: Inversion Of Control 控制反转DI: Dependency Injection 依赖注入1.控制反转 Inversion Of Control 的前世今生1.1 IOC理论产生的背景讨论控制反转之前先看看软件系统提出控制反转的前世今生。一个完整精密的软件系统组件之间就像齿轮协同工作相互耦合。一个零件不正常整个系统就崩溃了。系统对象之间耦合关系无法避免在项目规模和复杂度变大的情况下管理类之间的依赖关系将会很复杂。对象之间耦合度很高的系统架构师和开发人员对于系统的修改必然会出现牵一发而动全身的情形。对象之间耦合性依赖单元测试很复杂。1.2 IOC理论软件专家为此提出IOC理论用来实现对象之间的解耦。再来看看控制反转(IOC)到底为什么要起这么个名字我们来对比一下软件系统在没有引入IOC容器之前对象A依赖于对象B那么对象A在初始化或者运行到某一点的时候自己必须主动去创建对象B或者使用已经创建的对象B。无论是创建还是使用对象B控制权都在自己手上。软件系统在引入IOC容器之后这种情形就完全改变了由于IOC容器的加入对象A与对象B之间失去了直接联系所以当对象A运行到需要对象B的时候IOC容器会主动创建一个对象B注入到对象A需要的地方。通过前后对比我们不难看出对象A获得依赖对象B的过程由主动变为了被动行为控制权颠倒过来这就是“控制反转”的由来。1.3 控制反转 和 依赖注入有些人会把控制反转和依赖注入等同实际上有本质区别控制反转是一种思想依赖注入是一种设计模式。依赖注入是实现控制反转的一种方式但是控制反转还有其他实现方式例如说ServiceLocator服务定位器、依赖查找所以不能将控制反转和依赖注入等同。2 依赖注入 Dependency Injection依赖注入容器全权负责组件的装配它会把符合依赖关系的对象通过属性或者构造函数传递给需要的对象。符合依赖倒置原则高层模块不应该依赖低层模块两者都应该依赖其抽象2.1 ASP.NET Core依赖注入使用方式大体类似①. 定义依赖实现的接口或者抽象类②. 在服务容器中注册组件依赖 IServiceProvider③. 在构造函数中注入服务 框架会负责创建和销毁实例// 编写组件和服务
public interface IMyDependency
{string WriteMessage(string message);
}
---
public class MyDependency : IMyDependency
{public string WriteMessage(string message){return $MyDependency.WriteMessage Message: {message};}
}
// 注册组件和依赖下面注册的IMyDependency在一个web请求中有效
public void ConfigureServices(IServiceCollection services)
{services.AddScopedIMyDependency, MyDependency();services.AddRazorPages();
}
---
// 在构造函数注入组件
public class HomeController: AbpController
{private readonly IMyDependency _dep;public HomeController(IMyDependency dep){_dep dep;}public IActionResult Index(){var content _dep.WriteMessage($The Reflection instance is {_dep.GetType().FullName} );return Content(content);}
}
在请求某个服务时框架会完整解析出这个对象的依赖树和作用范围。上面的示例代码形成 req---HomeController---IMyDependency依赖树。 IMyDependency在每个web请求范围内使用同一服务实例。输出MyDependency.WriteMessage Message: The Reflection instance is TestDI.MyDependency2.2 对象生命周期根据现实需要前人从使用场景中总结出三种服务生命周期。ASP.NET Core提供了一个枚举ServiceLifetime-----------Singleton单例服务容器首次请求会创建后续都使用同一实例AddSingletonScoped特定范围在一个请求(连接)周期内使用一个示例AddScopedTransient瞬时服务容器每次请求都会创建一个实例AddTransient对于Scoped Service的理解在webappscoped service 会在请求结束时被销毁在EFCore使用AddDbContext默认注册的是特定范围的DbContext这意味在我们可以在一次sql连接内使用同一个DbContext实例进行多次DB操作。2.3 依赖注入实现原理结合理论、使用方式 猜测依赖注入的原理实现DI核心在于依赖注入容器IContainer该容器具有以下功能①.容器保存可用服务的集合// 要用的特定对象、特定类、接口服务②.注册提供一种方式将各种部件与他们依赖的服务绑定到一起// Add...函数或containerBuilder.Register函数③.解析点为应用程序提供一种方式来请求已配置的对象构造函数注入、属性注入.运行时框架会一层层通过反射构造实例最终得到完整对象。3.源码导航利用反射产生对象是依赖注入的核心过程这也是面试造航母时经常问到的。.NETSystem.Reflection、System.Type命名空间中的类可以获取可装配组件、类、接口的信息并提供了在运行时创建实例,调用动态实例方法、获取动态实例的能力。当我尝试从github源码中探究[依赖注入产生对象]的伪代码时文件/代码众多迷路了实际上我们可以在依赖树的尾部对象的构造函数手动抛出异常异常的调用栈就是一个天然的源码导航。于是我在上面示例代码的request---- HomeController---MyDependency MyDependency构造函数中添加异常代码 public MyDependency(){throw new Exception(exception content);}
结果如下图从Github Dependency Injection 库进入System.Reflection的调用分界线代码protected override object VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
{object[] parameterValues;if (constructorCallSite.ParameterCallSites.Length 0){parameterValues Array.Emptyobject();}else{parameterValues new object[constructorCallSite.ParameterCallSites.Length];for (var index 0; index parameterValues.Length; index){parameterValues[index] VisitCallSite(constructorCallSite.ParameterCallSites[index], context);}}try{return constructorCallSite.ConstructorInfo.Invoke(parameterValues);}catch (Exception ex) when (ex.InnerException ! null){ExceptionDispatchInfo.Capture(ex.InnerException).Throw();// The above line will always throw, but the compiler requires we throw explicitly.throw;}
}
黄色背景行就是.NET反射特性的体现对类型信息(构造函数、参数)使用Invoke方法产生对象。干货旁白控制反转是一种在软件工程中解耦合的思想调用方依赖接口或抽象类减少了耦合控制权交给了服务容器由容器维护注册项并将具体的实现动态注入到调用方。有些人会把控制反转和依赖注入等同实际上有本质区别控制反转是一种思想依赖注入是一种设计模式。依赖注入是实现控制反转的一种方式但是控制反转还有其他实现方式例如说ServiceLocator所以不能将控制反转和依赖注入等同。在运行时框架会解析依赖树、依赖图通过反射在运行期生成对象。ASP.NET Core 基于声明的访问控制到底是什么鬼我又踩坑了如何为HttpClient请求设置Content-Type标头临近年关修复ASP.NET Core因浏览器内核版本引发的单点登录故障手撕公司SSO登录原理实战解读ASP.NET Core身份认证ASP.NET Core应用注意这一点CTO会对你刮目相看