使用Autofac替换Asp.net core内置的依赖注入容器
Autofac是一个依赖注入容器。Autofac 和其他容器的不同之处是它和 C# 语言的结合非常紧密,在使用过程中对你的应用的侵入性几乎为零,更容易与第三方的组件集成。
通常情况下,Asp.net core内置的依赖注入实现已经足够用了,但Autofac确实提供了更多强大的功能,比如基于属性的注入,动态代理的AOP等。
准备工作
首先,安装两个nuget包:
- Autofac.Extensions.DependencyInjection
- Autofac.Extras.DynamicProxy
准备几个服务类:
public interface IMyService
{
void Show();
}
public class MyService : IMyService
{
public void Show()
{
Console.WriteLine($"MyService:{GetHashCode()}");
}
}
public class MyService2 : IMyService
{
public MyNameService NameService { get; set; }
public void Show()
{
Console.WriteLine($"MyService2:{GetHashCode()},NameService是否为空:{NameService==null}");
}
}
public class MyNameService
{
}
然后来认识一个接口:
public interface IServiceProviderFactory<TContainerBuilder>
这个接口是一个指定服务提供者的一个抽象泛型接口,所有的第三方依赖注入容器想在asp.net core中使用都需要实现它。我们自己也可以用它来实现自定义的依赖注入容器。
Autofac实现这个接口的类AutofacServiceProviderFactory,我们需要用它来替换内置的实现:
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
//这里注册服务
builder.Host.ConfigureContainer<ContainerBuilder>(builder =>
{
});
构造函数注入
注册:
//不指定默认是瞬时服务
builder.RegisterType<MyService>().As<IMyService>();
//单例
builder.RegisterType<MyService>().As<IMyService>().SingleInstance();
//域
builder.RegisterType<MyService>().As<IMyService>().InstancePerLifetimeScope();
autofac的生命周期作用域相对更加丰富,后续可以往后探索
使用:
[ApiController]
[Route("[controller]/[action]")]
public class MyController : ControllerBase
{
private readonly IMyService _myService;
public MyController(IMyService myService)
{
_myService = myService;
}
}
属性注入
注册:
builder.RegisterType<MyService>().As<IMyService>().PropertiesAutowired();
使用:
[ApiController]
[Route("[controller]/[action]")]
public class MyController : ControllerBase
{
public IMyService MyService { get; set; }
}
如果只是按照上面的流程操作,应该会是这样一个结果:构造函数注入成功,但是属性注入失败。原因如下:此时控制器本身的实例(以及它的处理)是由框架创建和拥有的,而不是由Autofac容器所有。构造函数的依赖性会有IServiceProvider解决,其他autofac的高级功能就无法使用了。此时应该:
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder =>
{
containerBuilder.RegisterType<MyService>().As<IMyService>().PropertiesAutowired();
var controllerBaseType = typeof(ControllerBase);
containerBuilder.RegisterAssemblyTypes(typeof(Program).Assembly)
.Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType)
.PropertiesAutowired();
});
builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
还有更多用法后续用到再更新。。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)