.net core autofac使用
nuget 引用
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="9.0.0" />
<PackageReference Include="Autofac.Extras.DynamicProxy" Version="7.1.0" />
AOP 拦截器
<PackageReference Include="Castle.Core" Version="5.1.1" />
上代码 替换容器 注意 AddControllersAsServices(); 这段代码要有
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()); builder.Host.ConfigureContainer<ContainerBuilder>(builder => builder.RegisterModule(new AutofacModuleRegister()));
builder.Services.AddControllers().AddControllersAsServices();
autofac注册容器代码 这里 代码很关键
public class AutofacModuleRegister : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
//获取 ControllerBase 的实现 也就是 Controller
Type[] controlllersTypes = typeof(Program).Assembly
.GetExportedTypes().Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray();
//将所有的 Controller 注入 并且可以属性注入 PropertiesAutowired
builder.RegisterTypes(controlllersTypes).PropertiesAutowired();
builder.RegisterType<WuLiangYe>();
}
}
这里 定义了 以酒为 主题 的示例代码
/// <summary>
/// 酒
/// </summary>
public interface IWine
{
string Drink();
}
/// <summary>
/// 五粮液
/// </summary>
public class WuLiangYe : IWine
{
public string Drink()
{
return $"喝得什么酒,喝的是五粮液酒";
}
}
/// <summary>
/// 茅台
/// </summary>
public class MaoTai : IWine
{
public string Drink()
{
return $"喝得什么酒,喝的是茅台酒";
}
}
上面 AutofacModuleRegister 中 注入了 最简单的 方式 实现类 使用 是
直接 属性就可以 public WuLiangYe WuLiangYe { get; set; } 那么为何 可以直接使用 因为 在 AutofacModuleRegister 中我写了 builder.RegisterTypes(controlllersTypes).PropertiesAutowired(); 这里说 controlller 可以使用 属性注入
现在继续 我修改 这种 方式 builder.RegisterType<WuLiangYe>().As<IWine>().InstancePerLifetimeScope();
public class AutofacModuleRegister : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
//获取 ControllerBase 的实现 也就是 Controller
Type[] controlllersTypes = typeof(Program).Assembly
.GetExportedTypes().Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray();
//将所有的 Controller 注入 并且可以属性注入 PropertiesAutowired
builder.RegisterTypes(controlllersTypes).PropertiesAutowired();
//builder.RegisterType<WuLiangYe>();
builder.RegisterType<WuLiangYe>().As<IWine>().InstancePerLifetimeScope();
}
}
使用 是这样的 public IWine Wine { get; set; } 也是我们经常使用的方式 符合多态性
如果 要实现 简单工厂模式敢问 阁下如何应对 话不多说上代码 WineEnum wineEnum 枚举选择
public class WineFactory
{
private readonly IComponentContext _context;
public WineFactory(IComponentContext context)
{
_context = context;
}
public IWine CreateWine(WineEnum wineEnum)
{
switch (wineEnum)
{
case WineEnum.WuLiangYe:
return _context.ResolveNamed<IWine>(WineEnum.WuLiangYe.GetTypeStr());
case WineEnum.MaoTai:
return _context.ResolveNamed<IWine>(WineEnum.MaoTai.GetTypeStr());
default:
return _context.ResolveNamed<IWine>(nameof(MaoTai));
}
}
}
这里修改了 枚举 注意红色字体 获取 GetField(@enum.ToString()) 上的特性
/// <summary>
/// 枚举酒
/// </summary>
public enum WineEnum
{
/// <summary>
/// 五粮液
/// </summary>
[WineEnumType("WuLiangYe")]
WuLiangYe = 0,
/// <summary>
/// 茅台
/// </summary>
[WineEnumType("MaoTai")]
MaoTai = 1
}
[AttributeUsage(AttributeTargets.Field)]
public class WineEnumTypeAttribute : Attribute
{
public string TypeStr { get; set; }
public WineEnumTypeAttribute(string typeStr)
{
TypeStr = typeStr;
}
}
public static class WineEnumTypeExtend
{
public static string GetTypeStr(this Enum @enum)
{
return @enum.GetType().GetField(@enum.ToString()).GetCustomAttribute<WineEnumTypeAttribute>()?.TypeStr ?? "";
}
}
上面 代码 我定义了简单工厂模式 获取实现实例 是 通过 IComponentContext , context.ResolveNamed<IWine>(nameof(WuLiangYe));
通过 name的方式 获取 那么 注册的时候该如何注册
public class AutofacModuleRegister : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
//获取 ControllerBase 的实现 也就是 Controller
Type[] controlllersTypes = typeof(Program).Assembly
.GetExportedTypes().Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray();
//将所有的 Controller 注入 并且可以属性注入 PropertiesAutowired
builder.RegisterTypes(controlllersTypes).PropertiesAutowired();
//builder.RegisterType<WuLiangYe>();
//builder.RegisterType<WuLiangYe>().As<IWine>().InstancePerLifetimeScope();
builder.RegisterType<WuLiangYe>().Named<IWine>(nameof(WuLiangYe)).InstancePerLifetimeScope();
builder.RegisterType<MaoTai>().Named<IWine>(nameof(MaoTai)).InstancePerLifetimeScope();
builder.RegisterType<WineFactory>();
}
}
Named方式注入
builder.RegisterType<WuLiangYe>().Named<IWine>(nameof(WuLiangYe)).InstancePerLifetimeScope();
builder.RegisterType<MaoTai>().Named<IWine>(nameof(MaoTai)).InstancePerLifetimeScope();
还有一种方式 是key的方式
builder.RegisterType<WuLiangYe>().Keyed<IWine>(nameof(WuLiangYe)).InstancePerLifetimeScope();
builder.RegisterType<MaoTai>().Keyed<IWine>(nameof(MaoTai)).InstancePerLifetimeScope();
获取如下
public class WineFactory
{
private readonly IComponentContext _context;
public WineFactory(IComponentContext context)
{
_context = context;
}
public IWine CreateWine(WineEnum wineEnum)
{
switch (wineEnum)
{
case WineEnum.WuLiangYe:
// return _context.ResolveNamed<IWine>(WineEnum.WuLiangYe.GetTypeStr());
return _context.ResolveKeyed<IWine>(WineEnum.WuLiangYe.GetTypeStr());
case WineEnum.MaoTai:
// return _context.ResolveNamed<IWine>(WineEnum.MaoTai.GetTypeStr());
return _context.ResolveKeyed<IWine>(WineEnum.MaoTai.GetTypeStr());
default:
return _context.ResolveNamed<IWine>(nameof(MaoTai));
}
}
}
综上所述 注册的方式
builder.RegisterType<WuLiangYe>().As<IWine>().InstancePerLifetimeScope();
builder.RegisterType<WuLiangYe>().Named<IWine>(nameof(WuLiangYe)).InstancePerLifetimeScope();
builder.RegisterType<MaoTai>().Keyed<IWine>(nameof(MaoTai)).InstancePerLifetimeScope();
builder.RegisterAssemblyModules()
改造一下 注册方式 不用手动注入了
//获取IWine 实现的 类型
Type[] wineTypes = Assembly.GetEntryAssembly().ExportedTypes.Where(type => typeof(IWine).IsAssignableFrom(type) && !type.IsInterface).ToArray();
foreach (var wineType in wineTypes)
{
builder.RegisterType(wineType).Keyed<IWine>(wineType.Name).InstancePerLifetimeScope();
}
public class AutofacModuleRegister : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
//获取 ControllerBase 的实现 也就是 Controller
Type[] controlllersTypes = typeof(Program).Assembly
.GetExportedTypes().Where(type => typeof(ControllerBase).IsAssignableFrom(type)).ToArray();
//将所有的 Controller 注入 并且可以属性注入 PropertiesAutowired
builder.RegisterTypes(controlllersTypes).PropertiesAutowired();
//获取IWine 实现的 类型
Type[] wineTypes = Assembly.GetEntryAssembly().ExportedTypes.Where(type => typeof(IWine).IsAssignableFrom(type) && !type.IsInterface).ToArray();
//builder.RegisterTypes(wineTypes).As<IWine>
foreach (var wineType in wineTypes)
{
builder.RegisterType(wineType).Keyed<IWine>(wineType.Name).InstancePerLifetimeScope();
}
//builder.RegisterType<WuLiangYe>();
//builder.RegisterType<WuLiangYe>().As<IWine>().InstancePerLifetimeScope();
//builder.RegisterType<MaoTai>().As<IWine>().InstancePerLifetimeScope();
//builder.RegisterType<WuLiangYe>().Named<IWine>(nameof(WuLiangYe)).InstancePerLifetimeScope();
//builder.RegisterType<MaoTai>().Named<IWine>(nameof(MaoTai)).InstancePerLifetimeScope();
//builder.RegisterType<WuLiangYe>().Keyed<IWine>(nameof(WuLiangYe)).InstancePerLifetimeScope();
//builder.RegisterType<MaoTai>().Keyed<IWine>(nameof(MaoTai)).InstancePerLifetimeScope();
builder.RegisterType<WineFactory>();
}
}
测试ok
浙公网安备 33010602011771号