Autofac在.NET Core中的依赖注入与AOP实践
1. 环境配置与NuGet包安装
首先需要引入以下NuGet包:
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="9.0.0" />
<PackageReference Include="Autofac.Extras.DynamicProxy" Version="7.1.0" />
<PackageReference Include="Castle.Core" Version="5.1.1" />
2. 替换默认DI容器
在Program.cs中配置Autofac作为服务容器,注意必须调用AddControllersAsServices():
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder =>
containerBuilder.RegisterModule(new AutofacModuleRegister()));
builder.Services.AddControllers().AddControllersAsServices();
3. 模块化注册配置
创建自定义Module类,批量注册Controller并支持属性注入:
public class AutofacModuleRegister : Autofac.Module
{
protected override void Load(ContainerBuilder containerBuilder)
{
// 批量注册Controller并启用属性注入
var controllerTypes = typeof(Program).Assembly
.GetExportedTypes()
.Where(type => typeof(ControllerBase).IsAssignableFrom(type))
.ToArray();
containerBuilder.RegisterTypes(controllerTypes).PropertiesAutowired();
// 注册WineFactory供工厂模式使用
containerBuilder.RegisterType<WineFactory>();
}
}
4. 示例业务接口与实现
/// <summary>
/// 酒饮接口
/// </summary>
public interface IWine
{
string Drink();
}
/// <summary>
/// 五粮液实现
/// </summary>
public class WuLiangYe : IWine
{
public string Drink() => "当前饮用:五粮液";
}
/// <summary>
/// 茅台实现
/// </summary>
public class MaoTai : IWine
{
public string Drink() => "当前饮用:茅台";
}
5. 依赖注入的三种方式
5.1 接口类型注入
// 注册
containerBuilder.RegisterType<WuLiangYe>().As<IWine>().InstancePerLifetimeScope();
// 使用(支持多态)
public IWine Wine { get; set; } // 在Controller中通过属性注入
5.2 命名注入
// 注册
containerBuilder.RegisterType<WuLiangYe>().Named<IWine>(nameof(WuLiangYe)).InstancePerLifetimeScope();
containerBuilder.RegisterType<MaoTai>().Named<IWine>(nameof(MaoTai)).InstancePerLifetimeScope();
// 通过IComponentContext解析
public IWine ResolveWine(IComponentContext context, string wineName)
{
return context.ResolveNamed<IWine>(wineName);
}
5.3 键值注入
// 注册
containerBuilder.RegisterType<WuLiangYe>().Keyed<IWine>(nameof(WuLiangYe)).InstancePerLifetimeScope();
containerBuilder.RegisterType<MaoTai>().Keyed<IWine>(nameof(MaoTai)).InstancePerLifetimeScope();
// 解析
public IWine ResolveWine(IComponentContext context, string wineName)
{
return context.ResolveKeyed<IWine>(wineName);
}
6. 工厂模式实现
利用枚举和自定义特性实现动态解析:
6.1 枚举与特性定义
public enum WineType
{
[WineAlias("WuLiangYe")]
WuLiangYe = 0,
[WineAlias("MaoTai")]
MaoTai = 1
}
[AttributeUsage(AttributeTargets.Field)]
public class WineAliasAttribute : Attribute
{
public string Alias { get; }
public WineAliasAttribute(string alias) => Alias = alias;
}
public static class WineTypeExtensions
{
public static string GetAlias(this WineType type)
{
var field = type.GetType().GetField(type.ToString());
return field?.GetCustomAttribute<WineAliasAttribute>()?.Alias ?? "";
}
}
6.2 工厂类实现
public class WineFactory
{
private readonly IComponentContext _context;
public WineFactory(IComponentContext context)
{
_context = context;
}
public IWine CreateWine(WineType wineType)
{
var alias = wineType.GetAlias();
return wineType switch
{
WineType.WuLiangYe => _context.ResolveKeyed<IWine>(alias),
WineType.MaoTai => _context.ResolveKeyed<IWine>(alias),
_ => _context.ResolveNamed<IWine>(nameof(MaoTai))
};
}
}
7. 自动化批量注册
通过反射自动注册所有实现了IWine接口的类型:
public class AutofacModuleRegister : Autofac.Module
{
protected override void Load(ContainerBuilder containerBuilder)
{
// Controller批量注册
var controllerTypes = typeof(Program).Assembly
.GetExportedTypes()
.Where(type => typeof(ControllerBase).IsAssignableFrom(type))
.ToArray();
containerBuilder.RegisterTypes(controllerTypes).PropertiesAutowired();
// 自动扫描并注册所有IWine实现
var wineTypes = Assembly.GetEntryAssembly()!
.ExportedTypes
.Where(type => typeof(IWine).IsAssignableFrom(type) && !type.IsInterface)
.ToArray();
foreach (var type in wineTypes)
{
containerBuilder.RegisterType(type)
.Keyed<IWine>(type.Name)
.InstancePerLifetimeScope();
}
containerBuilder.RegisterType<WineFactory>();
}
}
完成以上配置后,即可在Controller中通过属性注入或构造函数注入使用Autofac的依赖注入功能。推荐使用工厂模式处理需要动态解析多个实现类的场景,通过命名或键值注入可以灵活地根据运行时条件选择合适的实现。