C#.NET Autofac 详解(c# autoit)
bigegpt 2025-07-27 18:52 4 浏览
简介
Autofac 是一个成熟的、功能丰富的 .NET 依赖注入(DI)容器。
相比于内置容器,它额外提供:模块化注册、装饰器(Decorator)、拦截器(Interceptor)、强o的属性/方法注入支持、基于约定的程序集扫描等特性。
核心组件
- ContainerBuilder:用于注册服务的构建器
- IContainer:服务容器,负责解析依赖
- ILifetimeScope:生命周期作用域,管理对象生命周期
- Module:模块化注册的基类
核心特性
灵活的服务注册
- 支持按类型、实例、工厂、委托等多种方式注册;
- 支持开放泛型(IRepository<T> → Repository<T>)、条件注册。
生命周期管理
- 同样有 Singleton、InstancePerDependency(每次)、InstancePerLifetimeScope(等同于 Scoped)、InstancePerMatchingLifetimeScope(自定义标签作用域)等多种模式。
模块化(Module)
- 通过继承 Module 将相关注册逻辑封装为可复用、可拆分的单元;
- 支持自动加载整个程序集中的 Module。
装饰器(Decorator)
- 可以很方便地为某个服务添加一层或多层“外衣”,例如日志、缓存等横切逻辑。
拦截器(Interceptor)
- 基于 Castle DynamicProxy,自动在方法调用前后执行 AOP 逻辑,如性能监控、事务管理等。
程序集扫描
- 支持按命名空间、接口、特性等约定,将多个实现一行注册。
基本使用
引入 NuGet
Install-Package Autofac
Install-Package Autofac.Extensions.DependencyInjection # ASP.NET Core 集成
最简示例
using Autofac;
var builder = new ContainerBuilder();
// 1. 注册具体类型(默认使用 Transient 生命周期)
builder.RegisterType<OrderService>();
// 2. 注册接口与实现
builder.RegisterType<DbOrderRepository>().As<IOrderRepository>();
// 3. 注册单例
builder.RegisterType<AppConfig>().SingleInstance();
// 4. 注册工厂方法
builder.Register(c => new HttpClient()).InstancePerLifetimeScope();
builder.Register(c => {
var config = c.Resolve<IConfiguration>();
return new MyService(config.GetConnectionString("Default"));
}).As<IMyService>();
// 5. 注册已存在的实例
var logger = new NLogLogger();
builder.RegisterInstance(logger).As<ILogger>();
// 6. 注册开放泛型类型
builder.RegisterGeneric(typeof(MyRepository<>)).As(typeof(IRepository<>));
// 构建容器
var container = builder.Build();
// 从容器中解析服务
using (var scope = container.BeginLifetimeScope()) {
var service = scope.Resolve<OrderService>();
}
服务暴露 (Exposing Services)
As<T>(): 将组件暴露为特定服务类型 T (通常是接口)
builder.RegisterType<EmailSender>().As<IEmailSender>();
As<TService1, TService2>(): 将组件暴露为多个服务类型
builder.RegisterType<FileLogger>().As<ILogger, IFileLogger>();
AsImplementedInterfaces(): 将组件暴露为其实现的所有公共接口
builder.RegisterType<CustomerRepository>().AsImplementedInterfaces();
// 等同于 .As<ICustomerRepository, IRepository<Customer>, ...>()
AsSelf(): 将组件暴露为其自身类型。通常与其他.As()一起使用
builder.RegisterType<MySpecialService>().AsSelf().As<ISpecialService>();
生命周期(Scope)管理
生命周期 | 对应 Autofac 方法 | 场景 |
瞬时 / 每次依赖 | .InstancePerDependency() (默认) | 无状态、轻量对象 |
单例 / 容器范围 | .SingleInstance() | 线程安全、全局共享 |
每个生命周期作用域 | .InstancePerLifetimeScope() | 类似 ASP.NET Core 的 Scoped 模式 |
每个 HTTP 请求内单例 | .InstancePerRequest() | 仅 ASP.NET Core 集成支持 |
自定义标记作用域 | .InstancePerMatchingLifetimeScope("tag") | 某些特定操作需独立作用域 |
builder.RegisterType<CacheService>()
.As<ICacheService>()
.SingleInstance();
builder.RegisterType<DbContext>()
.AsSelf()
.InstancePerLifetimeScope();
var tagScope = container.BeginLifetimeScope("unitOfWork");
var ctx = tagScope.Resolve<DbContext>(); // 属于 "unitOfWork" 作用域
高级特性
属性注入
public class MyService {
[Inject] // 注入属性
public ILogger Logger { get; set; } // 自动注入的属性
}
// 注册时启用属性注入
builder.RegisterType<MyService>()
.ProjertiesAutowired();
手动解析
public class MyService
{
private readonly IComponentContext _context;
public MyService(IComponentContext context)
{
_context = context;
}
public void DoWork()
{
var userService = _context.Resolve<IUserService>();
// 使用 userService
}
}
命名与键控服务
// 注册多个实现,使用命名区分
builder.RegisterType<SqlDbContext>().Named<DbContext>("sql");
builder.RegisterType<MongoDbContext>().Named<DbContext>("mongo");
// 解析时指定名称
var sqlContext = scope.ResolveNamed<DbContext>("sql");
集合解析
自动解析所有实现某一接口的服务
container.RegisterType<UserService1>().As<IUserService>();
container.RegisterType<UserService2>().As<IUserService>();
// 解析所有实现
public class MultiService
{
private readonly IEnumerable<IUserService> _services;
public MultiService(IEnumerable<IUserService> services)
{
_services = services;
}
}
作用域管理
using (var scope = container.BeginLifetimeScope())
{
var service = scope.Resolve<IUserService>();
// 使用 service
}
高级作用域控制
- 嵌套作用域
using (var parentScope = container.BeginLifetimeScope())
{
var serviceA = parentScope.Resolve<ServiceA>();
using (var childScope = parentScope.BeginLifetimeScope())
{
var serviceB = childScope.Resolve<ServiceB>(); // 可访问父作用域实例
}
}
- 带标签作用域 (Tagged Scopes)
// 注册时标记作用域
builder.RegisterType<EmailSender>()
.As<IEmailSender>()
.InstancePerMatchingLifetimeScope("transaction");
// 使用标签创建作用域
using (var transactionScope = container.BeginLifetimeScope("transaction"))
{
var emailSender = transactionScope.Resolve<IEmailSender>(); // 事务内共享实例
}
模块化注册
当项目庞大或有多个子系统时,将注册逻辑封装在 Module 中,便于维护与复用。
// 定义模块
public class DataModule : Module {
protected override void Load(ContainerBuilder builder) {
builder.RegisterType<DbConnection>().As<IDbConnection>();
builder.RegisterType<OrderRepository>().As<IOrderRepository>();
}
}
// 注册模块
builder.RegisterModule<DataModule>();
public class RepositoryModule : Module
{
protected override void Load(ContainerBuilder builder)
{
// 自动扫描程序集内的 IRepository<> 实现
builder.RegisterAssemblyTypes(typeof(RepositoryModule).Assembly)
.AsClosedTypesOf(typeof(IRepository<>))
.InstancePerLifetimeScope();
}
}
// 在主程序里加载
var builder = new ContainerBuilder();
builder.RegisterModule<RepositoryModule>();
builder.RegisterModule(new SettingsModule(settings));
装饰器(Decorator)
给已有服务动态“套”上日志、缓存等功能,不需改动原实现。
// 原始服务
builder.RegisterType<OrderService>()
.As<IOrderService>();
// 装饰器:构造参数 inner 实例即被装饰的服务
builder.RegisterDecorator<LoggingOrderService, IOrderService>();
- 等同于:当解析 IOrderService 时,先创建 OrderService,再将其传给 LoggingOrderService 构造器。
AOP 拦截与动态代理
基于 Castle DynamicProxy,为接口或虚方法生成代理,在调用前后执行拦截逻辑。
引入包
Install-Package Autofac.Extras.DynamicProxy
Install-Package Castle.Core
// 定义拦截器
public class LoggingInterceptor : IInterceptor {
public void Intercept(IInvocation invocation) {
Console.WriteLine(#34;调用方法: {invocation.Method.Name}");
invocation.Proceed(); // 执行原始方法
Console.WriteLine(#34;方法返回: {invocation.ReturnValue}");
}
}
// 注册带拦截器的服务
builder.RegisterType<OrderService>()
.As<IOrderService>()
.EnableInterfaceInterceptors()
.InterceptedBy(typeof(LoggingInterceptor));
builder.RegisterType<LoggingInterceptor>();
程序集扫描与约定注册
根据命名、接口或特性,批量注册类型:
// 按接口后缀约定:所有以 "Service" 结尾的类,注册为它们所实现的接口
builder.RegisterAssemblyTypes(AppDomain.CurrentDomain.GetAssemblies())
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
条件注册
builder.RegisterType<SqlRepository>()
.As<IRepository>()
.When(c => c.Parameters.Any(p => p.Name == "useSql" && (bool)p.Value));
装配时验证
// 验证所有注册的服务可被解析
container.AssertConfigurationIsValid();
循环依赖解决
延迟注入
builder.Register(c => new ServiceA(c.Resolve<Lazy<IServiceB>>()));
builder.Register(c => new ServiceA(c.Resolve<Func<IServiceB>>()))
.As<IServiceA>();
builder.Register(c => new ServiceB(c.Resolve<IServiceA>()))
.As<IServiceB>();
builder.RegisterType<ServiceA>().As<IService>()
.OnlyIf(reg => Environment.IsDevelopment);
混合使用内置 DI 和 Autofac
builder.Services.AddScoped<IOtherService, OtherService>(); // 内置 DI
builder.Host.ConfigureContainer<ContainerBuilder>(container =>
{
container.RegisterType<UserService>().As<IUserService>();
});
与 ASP.NET Core 集成
在 Program.cs 中替换容器
// Program.cs
using Autofac.Extensions.DependencyInjection;
var builder = WebApplication.CreateBuilder(args);
// 使用 Autofac 替换默认 DI 容器
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
// 配置 Autofac 服务
builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder => {
containerBuilder.RegisterType<CustomService>().As<IService>();
containerBuilder.RegisterModule<MyModule>();
});
var app = builder.Build();
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureContainer<ContainerBuilder>(builder =>
{
builder.RegisterModule<RepositoryModule>();
//… 其他注册
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
在控制台应用中使用
var builder = new ContainerBuilder();
builder.RegisterModule<ApplicationModule>();
var container = builder.Build();
using (var scope = container.BeginLifetimeScope()) {
var service = scope.Resolve<IMyService>();
service.Run();
}
最佳实践与常见问题
避免服务定位器反模式
// 反模式:直接从容器解析服务
var service = container.Resolve<IMyService>();
// 正确做法:通过构造函数注入
public class MyConsumer {
private readonly IMyService _service;
public MyConsumer(IMyService service) { _service = service; }
}
- 上一篇:webapi 全流程(webapi怎么部署)
- 已经是最后一篇了
相关推荐
- C#.NET Autofac 详解(c# autoit)
-
简介Autofac是一个成熟的、功能丰富的.NET依赖注入(DI)容器。相比于内置容器,它额外提供:模块化注册、装饰器(Decorator)、拦截器(Interceptor)、强o的属性/方法注...
- webapi 全流程(webapi怎么部署)
-
C#中的WebAPIMinimalApi没有控制器,普通api有控制器,MinimalApi是直达型,精简了很多中间代码,广泛适用于微服务架构MinimalApi一切都在组控制台应用程序类【Progr...
- .NET外挂系列:3. 了解 harmony 中灵活的纯手工注入方式
-
一:背景1.讲故事上一篇我们讲到了注解特性,harmony在内部提供了20个HarmonyPatch重载方法尽可能的让大家满足业务开发,那时候我也说了,特性虽然简单粗暴,但只能解决95%...
- C# 使用SemanticKernel调用本地大模型deepseek
-
一、先使用ollama部署好deepseek大模型。具体部署请看前面的头条使用ollama进行本地化部署deepseek大模型二、创建一个空的控制台dotnetnewconsole//添加依赖...
- C#.NET 中间件详解(.net core中间件use和run)
-
简介中间件(Middleware)是ASP.NETCore的核心组件,用于处理HTTP请求和响应的管道机制。它是基于管道模型的轻量级、模块化设计,允许开发者在请求处理过程中插入自定义逻辑。...
- IoC 自动注入:让依赖注册不再重复劳动
-
在ASP.NETCore中,IoC(控制反转)功能通过依赖注入(DI)实现。ASP.NETCore有一个内置的依赖注入容器,可以自动完成依赖注入。我们可以结合反射、特性或程序集扫描来实现自动...
- C#.NET 依赖注入详解(c#依赖注入的三种方式)
-
简介在C#.NET中,依赖注入(DependencyInjection,简称DI)是一种设计模式,用于实现控制反转(InversionofControl,IoC),以降低代码耦合、提高可...
- C#从零开始实现一个特性的自动注入功能
-
在现代软件开发中,依赖注入(DependencyInjection,DI)是实现松耦合、模块化和可测试代码的一个重要实践。C#提供了优秀的DI容器,如ASP.NETCore中自带的Micr...
- C#.NET 仓储模式详解(c#仓库货物管理系统)
-
简介仓储模式(RepositoryPattern)是一种数据访问抽象模式,它在领域模型和数据访问层之间创建了一个隔离层,使得领域模型无需直接与数据访问逻辑交互。仓储模式的核心思想是将数据访问逻辑封装...
- C#.NET 泛型详解(c# 泛型 滥用)
-
简介泛型(Generics)是指在类型或方法定义时使用类型参数,以实现类型安全、可重用和高性能的数据结构与算法为什么需要泛型类型安全防止“装箱/拆箱”带来的性能损耗,并在编译时检测类型错误。可重用同一...
- 数据分析-相关性分析(相关性 分析)
-
相关性分析是一种统计方法,用于衡量两个或多个变量之间的关系强度和方向。它通过计算相关系数来量化变量间的线性关系,从而帮助理解变量之间的相互影响。相关性分析常用于数据探索和假设检验,是数据分析和统计建模...
- geom_smooth()函数-R语言ggplot2快速入门18
-
在每节,先运行以下这几行程序。library(ggplot2)library(ggpubr)library(ggtext)#用于个性化图表library(dplyr)#用于数据处理p...
- 规范申报易错要素解析(规范申报易错要素解析)
-
为什么要规范申报?规范申报是以满足海关监管、征税、统计等工作为目的,纳税义务人及其代理人依法向海关如实申报的行为,也是海关审接单环节依法监管的重要工作。企业申报的内容须符合《中华人民共和国海关进出口货...
- 「Eurora」海关编码归类 全球海关编码查询 关务服务
-
海关编码是什么? 海关编码即HS编码,为编码协调制度的简称。 其全称为《商品名称及编码协调制度的国际公约》(InternationalConventionforHarmonizedCo...
- 9月1日起,河南省税务部门对豆制品加工业试行新政7类豆制品均适用投入产出法
-
全媒体记者杨晓川报道9月2日,记者从税务部门获悉,为减轻纳税人税收负担,完善农产品增值税进项税额抵扣机制,根据相关规定,结合我省实际情况,经广泛调查研究和征求意见,从9月1日起,我省税务部门对豆制品...
- 一周热门
- 最近发表
- 标签列表
-
- mybatiscollection (79)
- mqtt服务器 (88)
- keyerror (78)
- c#map (65)
- xftp6 (83)
- bt搜索 (75)
- c#var (76)
- xcode-select (66)
- mysql授权 (74)
- 下载测试 (70)
- linuxlink (65)
- pythonwget (67)
- androidinclude (65)
- libcrypto.so (74)
- linux安装minio (74)
- ubuntuunzip (67)
- vscode使用技巧 (83)
- secure-file-priv (67)
- vue阻止冒泡 (67)
- jquery跨域 (68)
- php写入文件 (73)
- kafkatools (66)
- mysql导出数据库 (66)
- jquery鼠标移入移出 (71)
- 取小数点后两位的函数 (73)