☰分类导航

软件工程/服务与中间件
课程进度 52% · 第6/10章第6/10章 · 标签 1/6
— 1 —

依赖注入(DI)

原DI、日志、Session与中间件例子需要ASP.NET Core宿主、接口和实现。中间件缺少构造注入的部分已补齐。AddDistributedMemoryCache仍是单进程内存实现,不意味着跨实例共享。

ASP.NET Core内置依赖注入容器,支持三种生命周期:Singleton、Scoped、Transient。

对象寿命要与状态归属一致。一次请求的数据库上下文不应被长寿命单例捕获,否则多个请求可能共享失效或并发不安全对象。用两个请求各解析两次的实例标识推演复用关系,比仅背诵三个生命周期名更容易发现错误依赖。


```csharp
// 注册服务
builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddSingleton<ICacheService, CacheService>();
builder.Services.AddTransient<IEmailService, EmailService>();

// 使用依赖注入
public class UserController : ControllerBase {
    private readonly IUserService _userService;

    public UserController(IUserService userService) {
        _userService = userService;
    }
}
```
csharp
1
// 注册服务
2
builder.Services.AddScoped<IUserService, UserService>();
3
builder.Services.AddSingleton<ICacheService, CacheService>();
4
builder.Services.AddTransient<IEmailService, EmailService>();
5
 
6
// 使用依赖注入
7
public class UserController : ControllerBase {
8
private readonly IUserService _userService;
9
 
10
public UserController(IUserService userService) {
11
_userService = userService;
12
}
13
}

📖Scoped:每个HTTP请求一个实例。Singleton:全局唯一。Transient:每次注入都创建新实例

— 2 —

配置与日志

.NET提供了强大的配置系统和日志框架,支持多种配置源和日志输出目标。

配置系统负责来源与覆盖,业务仍需验证关键值存在且合法。结构化日志保留稳定模板与请求标识,便于聚合诊断;令牌、口令和整条连接字符串不进入日志。缓存和Session只是性能或临时会话工具,不应成为唯一业务事实存储。


```csharp
// 读取配置
var connectionString = builder.Configuration
    .GetConnectionString("DefaultConnection");

var appSettings = builder.Configuration
    .GetSection("AppSettings")
    .Get<AppSettings>();

// 日志记录
public class UserService {
    private readonly ILogger<UserService> _logger;

    public UserService(ILogger<UserService> logger) {
        _logger = logger;
    }

    public void CreateUser(User user) {
        _logger.LogInformation("Creating user: {Name}", user.Name);
        // 业务逻辑
    }
}
```
csharp
1
// 读取配置
2
var connectionString = builder.Configuration
3
.GetConnectionString("DefaultConnection");
4
 
5
var appSettings = builder.Configuration
6
.GetSection("AppSettings")
7
.Get<AppSettings>();
8
 
9
// 日志记录
10
public class UserService {
11
private readonly ILogger<UserService> _logger;
12
 
13
public UserService(ILogger<UserService> logger) {
14
_logger = logger;
15
}
16
 
17
public void CreateUser(User user) {
18
_logger.LogInformation("Creating user: {Name}", user.Name);
19
// 业务逻辑
20
}
21
}
DIIoCSingletonScoped配置日志