You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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实例。想请教两个问题:

  1. 如何在ASP.NET Core中正确使用依赖注入管理这些类?
  2. 这种依赖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);
    }
}

这样修改后,代码耦合度更低,可读性和可维护性都更好。


二、关于循环依赖的疑问:不会出现无限循环

你担心的循环依赖问题根本不会发生,原因如下:

  1. IConfiguration是ASP.NET Core框架默认注册的单例服务,DI容器只会在应用启动时创建它的一个实例,后续所有依赖它的服务都复用这个实例,不会重复创建。
  2. 循环依赖的前提是形成闭环依赖链(比如A依赖B,B又依赖A;或者A→B→C→A),而你的代码中:
    • UserDataAccess依赖DBConnect
    • DBConnect依赖IConfiguration
    • IConfiguration不依赖任何你的自定义类
      整个依赖链是线性的(UserDataAccess ← DBConnect ← IConfiguration),没有闭环,所以不可能出现无限循环。

简单来说,只有当两个或多个服务互相依赖时才会触发循环依赖问题,你的当前设计完全不存在这种情况,可以放心使用。


内容的提问来源于stack exchange,提问作者Yan Soo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 06:25:18