[TOC]
3.1 依赖注入
3.1.1 什么是控制反转,服务定位器和依赖注入
控制反转
在传统的编程方式中,如果一个对象A需要使用另一个对象B,那么A通常会自己负责创建B的实例 而控制反转改变了这一点:对象A不再负责创建对象B。相反,对象B的创建和注入由一个外部的“第三方”(通常是IoC容器)来完成。当需要时,这个“第三方”会把B的实例“注入”到A中。
3.1.2 .NET Core 依赖注入的基本使用
1.安装包,并引用对于的包
C
using Microsoft.Extensions.DependencyInjection;2.实现
C
var builder = WebApplication.CreateBuilder(args);
// 注册三种不同生命周期的服务
builder.Services.AddTransient<IRequestIdService, RequestIdService>();//每个请求一个数据库上下文
builder.Services.AddScoped<IRequestIdService, RequestIdService>();//每次发送邮件都新建
builder.Services.AddSingleton<IRequestIdService, RequestIdService>();//全局缓存,只实例化一次
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();
app.Run();C
[ApiController]
[Route("[controller]")]
public class TestController : ControllerBase
{
private readonly IServiceProvider _serviceProvider;
public TestController(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
[HttpGet]
public IActionResult Get()
{
// 每次 GetService 都会触发解析
var transient1 = _serviceProvider.GetRequiredService<IRequestIdService>().GetRequestId();
var transient2 = _serviceProvider.GetRequiredService<IRequestIdService>().GetRequestId();
var scoped1 = _serviceProvider.GetRequiredService<IRequestIdService>().GetRequestId();
var scoped2 = _serviceProvider.GetRequiredService<IRequestIdService>().GetRequestId();
var singleton1 = _serviceProvider.GetRequiredService<IRequestIdService>().GetRequestId();
var singleton2 = _serviceProvider.GetRequiredService<IRequestIdService>().GetRequestId();
return Ok(new
{
Transient = new[] { transient1.ToString(), transient2.ToString() }, // ❌ 不同
Scoped = new[] { scoped1.ToString(), scoped2.ToString() }, // ✅ 相同(同请求内)
Singleton = new[] { singleton1.ToString(), singleton2.ToString() } // ✅ 相同(全局)
});
}
}3.2 配置系统
3.2.1 配置系统的基本使用
注意要安装Microsoft.Extensions.Configuration和Microsoft.Extensions.Configuration.json 这两个包
c
using System;
using System.Reflection;
using System.Text.Json;
using Microsoft.Extensions.Configuration;
namespace ConsoleApp1
{
internal class Program
{
static void Main(string[] args)
{
/**
添加带解析配置文件 config.json,
文件内容为:
---
{
"name": "zack",
"proxy": {
"address": "192.168.1.9",
"port": 1088
},
"xyz": {
"ok": "啊手动阀手动阀"
}
}
---
optional:表示是否可选,true 的时候表示当配置文件不存在的时候,不会报错,false 相反
reloadOnChange:未见修改是否重新加载配置
config.json 文件中若为中文,注意编码问题
config["proxy:address"]等价于 config.GetSection("proxy:address").Value;
proxy:address 英文冒号:的意思是分层
*/
ConfigurationBuilder configBuilder = new ConfigurationBuilder();
configBuilder.AddJsonFile("config.json", optional: false, reloadOnChange: false);
IConfigurationRoot config = configBuilder.Build();
string name = config["name"];
string proxyAddress = config.GetSection("proxy:address").Value;
string xyz = config?.GetSection("xyz:ok")?.Value;
Console.OutputEncoding = System.Text.Encoding.UTF8;
Console.WriteLine($"name={name}");
Console.WriteLine($"address={proxyAddress}");
Console.WriteLine($"xyz:OK:OK={xyz}");
}
}
}