ASP.NET Core Web应用依赖注入使用及循环依赖疑问解答
ASP.NET Core依赖注入实践与循环依赖解惑
问题背景
我创建了一个ASP.NET Core Web应用,包含两个相关类:
public class DBConnect { private readonly IConfiguration _configuration; public DBConnect(IConfiguration config) { _configuration = config; } public SqlConnection createConnection() { return new SqlConnection("Driver=SQL Server;Server=localhost;Database=EcommerceApp;Uid={uid};Pwd={password}"); } }
以及继承自DBConnect的UserDataAccess:
public class UserDataAccess : DBConnect { public UserDataAccess(IConfiguration config) : base(config) { } public string getAllUsers() { using (SqlConnection conn = createConnection()) { // 数据库操作逻辑 } } }
这两个类都需要通过构造函数传入IConfiguration实例。想请教两个问题:
- 如何在ASP.NET Core中正确使用依赖注入管理这些类?
- 这种依赖
IConfiguration的设计会不会导致依赖注入的无限循环?
一、ASP.NET Core依赖注入的使用步骤
1. 将服务注册到DI容器
在.NET 6+项目的Program.cs(旧版本用Startup.cs)中,把你的自定义类注册到内置的DI容器里,根据业务需求选择合适的生命周期:
- AddScoped:每个HTTP请求周期创建一个实例(数据库访问类推荐用这个,符合请求隔离的原则)
- AddSingleton:整个应用生命周期只创建一个实例
- AddTransient:每次请求实例时都创建新的对象
示例代码:
var builder = WebApplication.CreateBuilder(args); // 注册DBConnect和UserDataAccess builder.Services.AddScoped<DBConnect>(); builder.Services.AddScoped<UserDataAccess>(); var app = builder.Build(); // 中间件配置... app.Run();
2. 通过构造函数注入使用服务
在需要用到这些类的地方(比如Controller、其他服务类),直接在构造函数中声明依赖,DI容器会自动完成实例的创建和注入,不需要手动new:
public class UsersController : ControllerBase { private readonly UserDataAccess _userDataAccess; // DI容器自动注入UserDataAccess实例,同时处理它依赖的DBConnect和IConfiguration public UsersController(UserDataAccess userDataAccess) { _userDataAccess = userDataAccess; } [HttpGet] public IActionResult GetAllUsers() { var userList = _userDataAccess.getAllUsers(); return Ok(userList); } }
3. 优化建议:避免直接依赖IConfiguration
直接依赖IConfiguration会让代码耦合度变高,推荐用强类型配置绑定的方式优化:
步骤1:创建强类型配置类
public class DbSettings { public string Server { get; set; } = string.Empty; public string Database { get; set; } = string.Empty; public string Uid { get; set; } = string.Empty; public string Password { get; set; } = string.Empty; }
步骤2:在appsettings.json中添加配置项
{ "DbSettings": { "Server": "localhost", "Database": "EcommerceApp", "Uid": "your-username", "Password": "your-password" } }
步骤3:绑定配置并注册到DI容器
// Program.cs中注册配置 builder.Services.Configure<DbSettings>(builder.Configuration.GetSection("DbSettings"));
步骤4:修改DBConnect依赖强类型配置
public class DBConnect { private readonly DbSettings _dbSettings; // 依赖IOptions<DbSettings>,容器会自动注入配置实例 public DBConnect(IOptions<DbSettings> dbSettings) { _dbSettings = dbSettings.Value; } public SqlConnection createConnection() { var connectionString = $"Server={_dbSettings.Server};Database={_dbSettings.Database};Uid={_dbSettings.Uid};Pwd={_dbSettings.Password};TrustServerCertificate=True"; return new SqlConnection(connectionString); } }
这样修改后,代码耦合度更低,可读性和可维护性都更好。
二、关于循环依赖的疑问:不会出现无限循环
你担心的循环依赖问题根本不会发生,原因如下:
IConfiguration是ASP.NET Core框架默认注册的单例服务,DI容器只会在应用启动时创建它的一个实例,后续所有依赖它的服务都复用这个实例,不会重复创建。- 循环依赖的前提是形成闭环依赖链(比如A依赖B,B又依赖A;或者A→B→C→A),而你的代码中:
UserDataAccess依赖DBConnectDBConnect依赖IConfigurationIConfiguration不依赖任何你的自定义类
整个依赖链是线性的(UserDataAccess←DBConnect←IConfiguration),没有闭环,所以不可能出现无限循环。
简单来说,只有当两个或多个服务互相依赖时才会触发循环依赖问题,你的当前设计完全不存在这种情况,可以放心使用。
内容的提问来源于stack exchange,提问作者Yan Soo
相关产品推荐
相关产品推荐

