全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

C#的依赖注入(DI)是什么?面向初学者的DI核心概念与实例教程

依赖注入通过外部注入对象实现解耦,提升代码可测试性与维护性。示例中UserService不再自行创建UserDataAccess,而是通过构造函数接收IUserDataAccess实现,.NET内置容器在Program.cs中注册服务生命周期(Scoped/Singleton/Transient),运行时自动注入实例,测试时可替换为Mock对象,避免硬编码依赖,统一管理对象创建,降低耦合度。

依赖注入(Dependency Injection,简称 DI)是 C# 和 .NET 开发中一个非常重要的设计模式。它帮助我们写出更松耦合、更容易测试和维护的代码。如果你刚接触这个概念,可能会觉得抽象,但其实它的核心思想很简单:不要自己创建对象,而是让外部系统把需要的对象“送进来”。

什么是依赖?

在面向对象编程中,一个类经常需要使用另一个类的功能。比如,有一个 UserService 类需要访问数据库,它可能依赖于一个 UserDataAccess 类。这种“需要别人帮忙完成工作”的关系就是“依赖”。

示例:

假设你有一个用户服务类:

public class UserService
{
    private UserDataAccess _dataAccess;
public UserService()
{
    _dataAccess = new UserDataAccess(); // 手动创建依赖
}

public string GetUser(int id)
{
    return _dataAccess.GetUserById(id);
}

}

这里的问题是:UserService 自己创建了 UserDataAccess,导致两者紧紧绑在一起。如果将来想换成 Mock 数据或不同的实现,就必须修改代码 —— 这不利于测试和扩展。

依赖注入的核心思想

DI 的基本思路是:把依赖项从外部“注入”进来,而不是在类内部自己 new 出来。最常见的方式是通过构造函数传入。

改写上面的例子:

public class UserService
{
    private readonly IUserDataAccess _dataAccess;
public UserService(IUserDataAccess dataAccess)  // 依赖通过构造函数传入
{
    _dataAccess = dataAccess;
}

public string GetUser(int id)
{
    return _dataAccess.GetUserById(id);
}

}

现在,UserService 不关心具体是谁提供数据访问功能,只要对方符合 IUserDataAccess 接口就行。这就实现了“解耦”。

.NET 中的内置 DI 容器

.NET Core 及以后版本内置了依赖注入容器,可以在程序启动时注册服务,并自动把它们注入到需要的地方。

步骤如下:

  • 定义接口和实现
  • Program.csStartup.cs 中注册服务
  • 在类中通过构造函数接收依赖

完整示例:

// 1. 定义接口
public interface IUserDataAccess
{
    string GetUserById(int id);
}

// 2. 实现接口 public class UserDataAccess : IUserDataAccess { public string GetUserById(int id) { return $"User {id} from database"; } }

// 3. 使用依赖的服务 public class UserService { private readonly IUserDataAccess _dataAccess;

public UserService(IUserDataAccess dataAccess)
{
    _dataAccess = dataAccess;
}

public string GetUser(int id)
{
    return _dataAccess.GetUserById(id);
}

}

Program.cs(.NET 6+)中注册服务:

var builder = WebApplication.CreateBuilder(args);

// 注册服务:告诉容器 IUserDataAccess 应该用 UserDataAccess 来实例化 builder.Services.AddScoped(); builder.Services.AddScoped();

var app = builder.Build();

// 示例:在 Minimal API 中使用 app.MapGet("/user/{id}", (int id, UserService userService) => { return userService.GetUser(id); });

app.Run();

当你访问 /user/1 时,.NET 会自动创建 UserService 实例,并把已注册的 IUserDataAccess 实现注入进去。

三种常见的服务生命周期

注册服务时,你需要选择它的生命周期:

  • Scoped:每次 HTTP 请求创建一次(适用于 Web 应用)
  • Singleton:整个程序运行期间只创建一次
  • Transient:每次请求都创建新实例

一般情况下:

  • 数据访问类用 Scoped
  • 工具类或无状态服务可用 Singleton
  • 轻量级、有状态的临时对象可用 Transient

为什么使用 DI?好处有哪些?

  • 易于测试:你可以注入 Mock 对象进行单元测试
  • 解耦代码:类之间不再硬编码依赖关系
  • 便于维护:更换实现时只需修改注册代码,无需改动业务类
  • 统一管理对象创建:避免手动 new 导致的资源浪费或错误

举个测试的例子:

// 测试时可以注入一个假的数据访问层
public class MockUserDataAccess : IUserDataAccess
{
    public string GetUserById(int id) => $"Mock User {id}";
}

// 单元测试中 var mockDataAccess = new MockUserDataAccess(); var userService = new UserService(mockDataAccess); // 注入模拟对象 var result = userService.GetUser(1); Console.WriteLine(result); // 输出: Mock User 1

这样不需要真实数据库就能测试逻辑。

基本上就这些。依赖注入不是魔法,它只是一个帮你更好地组织代码的工具。刚开始可能会觉得多写了不少接口和注册代码,但随着项目变大,你会发现它带来的清晰结构和灵活性非常值得。


# 编码  # app  # access  # 工具  # 面向对象编程  # c#  # 数据访问  # .net  # 为什么  # 面向对象  # 构造函数  # 接口  # 对象  # 数据库  # http  # 是一个  # 如果你  # 是在  # 你可以  # 就能  # 不需要  # 当你  # 只需  # 帮你  # 适用于 


相关文章: 建站之星代理如何优化在线客服效率?  网站制作免费,什么网站能看正片电影?  建站之星ASP如何实现CMS高效搭建与安全管理?  建站之星在线客服如何快速接入解答?  洛阳网站制作公司有哪些,洛阳的招聘网站都有哪些?  建站之星免费模板:自助建站系统与智能响应式一键生成  可靠的网站设计制作软件,做网站设计需要什么样的电脑配置?  高配服务器限时抢购:企业级配置与回收服务一站式优惠方案  为什么Go需要go mod文件_Go go mod文件作用说明  大型企业网站制作流程,做网站需要注册公司吗?  建站ABC备案流程中有哪些关键注意事项?  微信小程序 五星评分(包括半颗星评分)实例代码  相亲简历制作网站推荐大全,新相亲大会主持人小萍萍资料?  定制建站策划方案_专业建站与网站建设方案一站式指南  ,怎么在广州志愿者网站注册?  如何在Golang中指定模块版本_使用go.mod控制版本号  建站OpenVZ教程与优化策略:配置指南与性能提升  javascript基本数据类型及类型检测常用方法小结  焦点电影公司作品,电影焦点结局是什么?  网站制作培训多少钱一个月,网站优化seo培训课程有哪些?  如何用西部建站助手快速创建专业网站?  保定网站制作方案定制,保定招聘的渠道有哪些?找工作的人一般都去哪里看招聘信息?  建站之星后台密码遗忘?如何快速找回?  西安制作网站公司有哪些,西安货运司机用的最多的app或者网站是什么?  标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?  胶州企业网站制作公司,青岛石头网络科技有限公司怎么样?  南宁网站建设制作定制,南宁网站建设可以定制吗?  网站建设设计制作营销公司南阳,如何策划设计和建设网站?  模具网站制作流程,如何找模具客户?  专业企业网站设计制作公司,如何理解商贸企业的统一配送和分销网络建设?  交易网站制作流程,我想开通一个网站,注册一个交易网址,需要那些手续?  广东企业建站网站优化与SEO营销核心策略指南  导航网站建站方案与优化指南:一站式高效搭建技巧解析  如何在阿里云虚拟服务器快速搭建网站?  ,在苏州找工作,上哪个网站比较好?  智能起名网站制作软件有哪些,制作logo的软件?  如何制作一个表白网站视频,关于勇敢表白的小标题?  建站之星后台密码如何安全设置与找回?  实现点击下箭头变上箭头来回切换的两种方法【推荐】  移动端手机网站制作软件,掌上时代,移动端网站的谷歌SEO该如何做?  台州网站建设制作公司,浙江手机无犯罪记录证明怎么开?  如何通过.red域名打造高辨识度品牌网站?  建站为何优先选择香港服务器?  PHP 500报错的快速解决方法  h5网站制作工具有哪些,h5页面制作工具有哪些?  头像制作网站在线观看,除了站酷,还有哪些比较好的设计网站?  如何通过西部数码建站助手快速创建专业网站?  太平洋网站制作公司,网络用语太平洋是什么意思?  C++中的Pimpl idiom是什么,有什么好处?(隐藏实现)  视频网站制作教程,怎么样制作优酷网的小视频? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。