.Net依赖注入、控制反转
依赖项是指另一个对象所依赖的对象。 使用其他类所依赖的 WriteMessage
方法检查以下 MyDependency
类:
public class MyDependency
{
public void WriteMessage(string message)
{
Console.WriteLine($"MyDependency.WriteMessage called. Message: {message}");
}
}
类可以创建 MyDependency
类的实例,以便利用其 WriteMessage
方法。 在以下示例中,MyDependency
类是 IndexModel
类的依赖项:
public class IndexModel : PageModel
{
private readonly MyDependency _dependency = new MyDependency(); public void OnGet()
{
_dependency.WriteMessage("IndexModel.OnGet");
}
}
该类创建并直接依赖于 MyDependency
类。 代码依赖项(如前面的示例)会产生问题,应避免使用,原因如下:
- 要用不同的实现替换
MyDependency
,必须修改IndexModel
类。 - 如果
MyDependency
具有依赖项,则必须由IndexModel
类对其进行配置。 在具有多个依赖于MyDependency
的类的大型项目中,配置代码将分散在整个应用中。 - 这种实现很难进行单元测试。
依赖关系注入通过以下方式解决了这些问题:
- 使用接口或基类将依赖关系实现抽象化。
- 在服务容器中注册依赖关系。 ASP.NET Core 提供了一个内置的服务容器 IServiceProvider。 服务通常已在应用的
Program.cs
文件中注册。 - 将服务注入到使用它的类的构造函数中。 框架负责创建依赖关系的实例,并在不再需要时将其释放。
在示例应用中, 接口定义 WriteMessage
方法:
public interface IMyDependency
{
void WriteMessage(string message);
}
此接口由具体类型 MyDependency
实现:
public class MyDependency : IMyDependency
{
public void WriteMessage(string message)
{
Console.WriteLine($"MyDependency.WriteMessage Message: {message}");
}
}
示例应用使用具体类型 MyDependency
注册 IMyDependency
服务。 AddScoped 方法使用范围内生存期(单个请求的生存期)注册服务。
using DependencyInjectionSample.Interfaces;
using DependencyInjectionSample.Services; var builder = WebApplication.CreateBuilder(args); builder.Services.AddRazorPages(); builder.Services.AddScoped<IMyDependency, MyDependency>(); var app = builder.Build();
在示例应用中,请求 IMyDependency
服务并用于调用 WriteMessage
方法:
public class Index2Model : PageModel
{
private readonly IMyDependency _myDependency; public Index2Model(IMyDependency myDependency)
{
_myDependency = myDependency;
} public void OnGet()
{
_myDependency.WriteMessage("Index2Model.OnGet");
}
}
通过使用 DI 模式,控制器或 Razor 页面:
- 不使用具体类型
MyDependency
,仅使用它实现的IMyDependency
接口。 这样可以轻松地更改实现,而无需修改控制器或 Razor 页面。 - 不创建
MyDependency
的实例,这由 DI 容器创建。
这样就做到了完美解耦,我们的控制器也就不再依赖于某个具体的对象了。
我们书写这样的代码,也符合设计模式中的:继承原则,单一职责原则,开放封闭原则,依赖倒转原则。
上述说的设计模式原则简单介绍下:
关于继承无需多说
所谓单一职责原则是指:就一个类而言,应该仅有一个引起它变化的原因
所谓开闭原则是指:对于扩展是开放的,对于修改是封闭的(ASD原则)
依赖倒转原则是指:高层不应该依赖底层模块(强内聚,松耦合),就上述代码中的控制器(IndexModel、Index2Model)属于高层模块,接口及其实现类,服务注册类/方法(startup.cs中的ConfigureServices)属于底层模块。
参考博客:https://www.cnblogs.com/chenwolong/p/Scoped.html
微软文档:https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-6.0
最新文章
- Linux GCC常用命令
- JS基础知识总结
- Sublime Text 3 常用插件以及安装方法(vue 插件)
- github上一款特别的侧滑
- leetcode course shedule
- Juniti学习总结
- 【Android 界面效果12】EditText中的多行输入问题
- Lua基础之table详解
- 【转】IO - 同步,异步,阻塞,非阻塞 (亡羊补牢篇)
- 一篇非常全面的freemarker教程
- poj 3253 Fence Repair 优先队列
- Spark 核心概念 RDD 详解
- <;<;Senium2自动化测试>;>;读书笔记一
- STL:map/multimap用法详解
- java @Service 引入什么包
- VirtualBox中CentOS7.2 网络配置(固定IP+联网)
- java8_api_math
- Ubuntu下软件安装的几种方式,apt,dpkg工具的使用
- window炫丽cmd的别名cmder
- easywechat (在thinkphp5中使用easywechat完成微信网页认证)
热门文章
- 数电第六周周结_by_yc
- hook 无限debugger(猿人学第十四题)
- 我做了第一个ChatGPT .net api聊天库
- 第二篇:前端基础之CSS
- [whk] 解三元一次方程
- APP上架因收集个人信息问题被拒绝该怎么解决?
- java8新特性学习笔记
- BBS项目功能编写逻辑思路汇总
- Entrypoint undefined = index.html html-webpack-plugin 错误ERROR in Error: Child compilation failed: Module build failed (from ./node_modules/html-webpack-plu SyntaxError: Unexpected token )
- Keil 5(Keil C51)安装与注册 [ 图文教程 ]