.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

 

 

 

 

 

 

 

  

 


  

 

posted on 2024-05-22 18:02  是水饺不是水饺  阅读(23)  评论(0)    收藏  举报

导航