当你用.NET写第一个Web API时,代码干净得像刚拆封的键盘。Controller调Service,Service调Repository,三层架构整整齐齐,编译通过的那一刻,你觉得自己掌握了软件工程的精髓。
三个月后,噩梦开始。
产品说要加日志。你在17个文件里手动new了Logger。技术总监要换数据库,你打开VS发现42处Repository实例需要改构造参数。写单元测试时,你盯着那堆硬编码的依赖关系,终于理解了什么叫"牵一发而动全身"。
手动创建对象的隐性账单
上面那段"简单"代码的问题,在于它把依赖关系焊死在代码里。UserController必须知道UserRepository的存在,UserService的构造参数变了,所有调用方都得跟着改。这不是耦合,是混凝土浇筑。
更隐蔽的成本在测试端。想Mock掉数据库?手动new的对象根本换不了实现。你的"单元测试"被迫连上了真实的SQL Server,跑完一套比泡碗面还慢。
依赖注入是怎么解这个扣的
.NET内置的DI容器(Dependency Injection,依赖注入)干了一件事:把"谁创建对象"和"谁使用对象"拆开。你在Startup.cs里注册一次服务,框架自动帮你组装对象图。
改造后的Controller长这样:
public class UserController : ControllerBase { private readonly IUserService _service; public UserController(IUserService service) { _service = service; } }
new去哪了?被框架吞了。你只管声明需要什么,容器负责把匹配的实例塞进来。换数据库?改一行注册代码。写测试?传入Mock对象就行。
为什么老手从不提醒你
这事有点反直觉:教程里的"简单示例"恰恰是最危险的代码。它让你误以为手动new是正道,等你项目大到疼的时候,重构成本已经高到让人想跑路。
微软的文档其实埋了线索——官方模板生成的项目默认带DI容器,但新手往往跳过那部分,直奔"能跑就行"。
你现在回头看自己的代码库,有多少个new关键字正在悄悄收利息?
热门跟贴