Skip to content

[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}");


        }
    }
}

使用选项方式读取数据