.NET6 引入Autofac
因为 .NET6自带的 IOC 容器不支持 属性注入 方法注入 也不支持 Config.json 配置文件
所以正式项目开发中 一般引入第三方开源的Autofac 容器
1.Nuget引入Autofac程序集
Autofac
Autofac.Extensions.DependencyInjection
2.Program.cs 类中 注册Autofac
在Program.cs 类 var app = builder.Build(); 前面 添加这一段 代码
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
引入AutofacServiceProvider工厂

3.添加Autofac 注册函数
方法一 用代码注册服务
理论上 Autofac 可以直接 接管 NET6自带的 IOC 容器 的所有注册 所以如前面已经写了
用 .Net6 IOC 注册的服务 这里就可以不用添加,但即然使用了Autofac 还是建议将服务注册 写在Autofac专用的函数中
在引入Autofac 代码下方直接 添加如下代码:
//Autofac 专用函数注册
IHostBuilder hostBuilder = builder.Host.ConfigureContainer(builder =>
{
//这里注册关系
builder.RegisterType().As();
builder.RegisterType().As();
});
这里注册规则是
builder.RegisterType<
// 实现类 接口类 作用域生命周期
builder.RegisterType().As().InstancePerLifetimeScope();
// 单例生命周期
builder.RegisterType().As().SingleInstance();
// 瞬时生命周期(不写默认就是瞬时)
builder.RegisterType().As().InstancePerDependency();
方法二 配置文件中注册服务
如果服务经常变动 一套代码 部署不同的项目 服务切来切去比较频繁 最好是在配置文件中配置
第一步 Nuget引入 Autofac.Configuration 包
第二步 在项目中添加 CfgFile.json文件夹
文件夹下创建一个 Autofac.json 文件

注册服务的信息以json的格式写在配置文件中 内容如下:
{
"components": [
//规则如下
//{
// "type": "具体实现类的完整类名(命名空间.类名),具体实现类程序集名",
// "services": [
// {
// "type": "接口的完整类名(命名空间.类名),接口所在的程序集"
// }
// ],
//"instanceScope": "single-instance", //生命周期
//"injectProperties": true // 是否要支持属性注入
//},
{
"type": "Business.ServiceForDDD.VirtualWalletServiceApp,Business.ServiceForDDD", //具体实现类的完整类名,程序集名
"services": [
{
"type": "Business.Interface.IVirtualWalletService,Business.Interface" //接口的完整类名,程序集名
}
],
"instanceScope": "Instance-PerLifetimeScope", ////(生命周期 Instance-PerLifetimeScope 作用域 Instance-PerDependency 瞬时 single-instance 单例)
"injectProperties": false // 开启属性注入
},
{
"type": "VirtualWalletRepository.Entity.AccountDBContext,VirtualWalletRepository", //具体实现类的完整类名,程序集名
"services": [
{
"type": "Microsoft.EntityFrameworkCore.DbContext,Microsoft.EntityFrameworkCore" //接口的完整类名,程序集名
}
],
"instanceScope": "Instance-PerDependency", //(生命周期 Instance-PerLifetimeScope 作用域 Instance-PerDependency 瞬时 single-instance 单例)
"injectProperties": false // 开启属性注入
}
]
}
第三步
Autofac 专用注册函数中改成如果代码表示 读取配置文件来找 注册的关系
IHostBuilder hostBuilder = builder.Host.ConfigureContainer(builder =>
{
IConfigurationBuilder config = new ConfigurationBuilder();
IConfigurationSource autofacJsonConfigSource = new JsonConfigurationSource()
{
Path = "CfgFile/Autofac.json",
Optional = false,//boolean,默认就是false,可不写
ReloadOnChange = true,//同上
};
config.Add(autofacJsonConfigSource);
ConfigurationModule module = new ConfigurationModule(config.Build());
builder.RegisterModule(module);
});
4.Autofac 单抽象多实现的方法-1直接引用具体
1.同一个接口 注册了多个实现类 后注入的类会覆盖 最后实例化的是最后个的注册的实现类
2.一个抽象多个实例,都注册了,可以通过一个IEnumerable<抽象>,当做构造函数参数,可以获取到所有注册的具体的实例
3.注册一个抽象的多个实例资源,如下方式注册,可以在控制器的构造函数中,使用具体实现类型作为参数类型,可以匹配到不同到具体类型实例
//一次性注册继承该IVirtualWalletService接口的所有的类
builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource(t =>
t.IsAssignableTo()));
4.构造函数注入的时候直接注入具体的类
public VirtualWalletService _WalletService { get; }
public VirtualWalletController(VirtualWalletService WalletService)
{
this._WalletService = WalletService;
}
5.Autofac 创建 Module 类 分组注册
有些相同功能的类注册 想放到一起可以单独创建一个 Module 类 都在类里注册好
再 Program.cs 类中一次性注册整个 Module 组
新建一个类 继承 Autofac.Module
public class AutofacModule : Autofac.Module
{
//注册分类
protected override void Load(ContainerBuilder builder)
{
//所有继承ITestServiceA的都注册了
builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource(t => t.IsAssignableTo()));
}
}
在Program.cs 中 Autofac 专用注册函数里直接注册整组
IHostBuilder hostBuilder = builder.Host.ConfigureContainer(builder =>
{
builder.RegisterModule(); //注册整 个Module单元
});