.NET主流IOC容器有4个:Microsoft.Extensions.DependencyInjection(官方内置,轻量但功能有限)、Autofac(最成熟第三方,支持高级生命周期和模块化注册)、Unity与Ninject(已停止维护,仅适用于遗留项目)。

C# 中主流、生产可用的 IOC 容器有 4 个核心选择:Microsoft.Extensions.DependencyInjection(官方内置)、Autofac、Unity、Ninject。其中前两个是当前最推荐的,后两个已基本停止活跃维护或仅用于遗留项目。
Microsoft.Extensions.DependencyInjection 是什么?怎么用?
这是 .NET Core 2.0+ 及所有现代 .NET(5/6/7/8/9)默认集成的轻量级 DI 容器,不是第三方库,而是 SDK 自带。它不支持高级生命周期(如作用域嵌套、命名作用域),但足够支撑绝大多数 Web API、Worker Service 和控制台应用。
- 注册服务只需调用
builder.Services.AddSingleton等扩展方法() - 在
Program.cs中通过host.Services.GetService解析() - 只支持三种生命周期:
AddSingleton、AddScoped、AddTransient—— 没有InstancePerMatchingLifetimeScope这类 Autofac 特性 - 不能解析构造函数中带非注册参数的类型(比如
public Logger(string name)会失败,除非显式配置)
Autofac 为什么仍是首选第三方容器?
当项目需要更精细的生命周期控制、模块化注册、属性注入、动态代理或与 ASP.NET Core 深度集成时,Autofac 是目前最成熟、文档最全、社区最活跃的替代方案。
- 支持
InstancePerLifetimeScope、InstancePerMatchingLifetimeScope("admin")、InstancePerOwned等高级作用域模式() - 可按程序集、命名空间或自定义条件批量注册(
RegisterAssemblyTypes) - 能无缝替换 Microsoft 默认容器:只需在
Program.cs调用builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()) - 注意:NuGet 包名是
Autofac.Extensions.DependencyInjection(用于集成),不是Autofac单独引用
Unity 和 Ninject 还能用吗?
不建议新项目使用。Unity 已于 2021 年由微软正式归档(archive),Ninject 自 2020 年起无实质更新,且两者对 .NET 6+ 的泛型主机(Generic Host)支持不完善,容易在 Host.CreateApplicationBuilder 场景下报 InvalidOperationException: No service for type '...' has been registered。
HTShop网上购物系统由恒天网络科技有限公司根据国际先进技术和国内商务特点自主版权开发的一款具有强大功能的B2C电子商务网上购物平台。HTShop以国际上通用流行的B/S(浏览器/服务器)模式进行设计,采用微软公司的ASP.NET(C#)技术构建而成。 2007-11-10 HTShop CS 通用标准版 v1.1.11.10 更新内容自由更换模版功能开放 修改了购买多款商品,会员中心订单只显示
- 如果你正在维护老 WPF 或 .NET Framework 4.x 项目,它们仍可工作
- 迁移到新项目时,遇到
Resolve报错或构造函数注入失败,大概率是容器未正确接管 Host 生命周期() - Unity 的
RegisterType语法看似简洁,但调试依赖树非常困难 —— 缺少像 Autofac 的().As() Resolve这种开箱即用的集合解析能力>()
自己写一个简易 IOC 容器靠谱吗?
仅限学习或极简脚本场景。用 Dictionary + Activator.CreateInstance 实现注册/解析,确实几小时就能跑通,但很快会撞墙:
- 无法处理循环依赖(一调用就栈溢出)
- 不支持泛型注册(
Register会失败)>() - 生命周期完全靠手动
new/Dispose管理,没有作用域自动释放机制 - 没有线程安全保障 —— 多次并发
GetService可能创建重复单例
private readonly Dictionary_mappings = new(); public void Register () where TImplementation : class, TService { _mappings[typeof(TService)] = typeof(TImplementation); } public TService GetService () { var implType = _mappings[typeof(TService)]; return (TService)Activator.CreateInstance(implType); }
真正卡住人的从来不是“选哪个容器”,而是什么时候该用作用域、什么时候必须用单例、以及如何让 Worker Service 或中间件里的对象也参与 DI 生命周期——这些细节,比容器名字重要得多。









