Autofac

发布时间 2023-08-10 22:58:45作者: 老菜农

AutoFac

(1)使用

  1. NuGet 引入包Autofac.Extention

  2. .net 6 program.cs 中 替換原生IOC容器, 此时原生的IOC容器中的东西被转移到Autofac里, 在ConfigureContainer中不注册也行, 不是并行状态

    // 替换原生IOC容器 => autofac容器
    builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
  3. .net 6 program.cs 中 使用autofac容器

    1. 默认不写为瞬态

    2. InstancePerLifetimeScope() 线程

    3. .SingleInstance()单例

    //使用autofac容器
    builder.Host.ConfigureContainer<ContainerBuilder>(builder => 
            {
                builder.RegisterType<服务接口实现类>().As<服务接口类>().注册状态();
            });
  4. 使用

    namespace SecondDemo.Controllers
    {
        [ApiController]
        [Route("/api/[controller]/[action]")]
        public class TestAutofacController : ControllerBase
        {
            public IUserService UserService { get; }
    ​
            public TestAutofacController(IUserService userService)
            {
                UserService = userService;
            }
    ​
            [HttpGet(Name = "TestAutofacUser", Order = 0)]
            public string Get()
            {
                return UserService.GetUserName();
            }
        }
    }
  • 使用服务提供者, 查看容器是替换还是并行

    • autofac替换前是MicosoftExtensionServiceProviderEngineScope

    • 替换后是Autofac.Extension.DenpendencyInjection.AutoFacServiceProvider

public XxxController(IServceProvider, serviceProvider, IUserService userSerivce)
{
    this.UserService = userService
}

(2)泛型Service注入使用typeof()

public interface IBaseService<T>
{
    string GetTName(); 
}
public class BaseService<T> : IBaseService<T>
{
    /// <summary>
    /// 查找类的名字
    /// </summary>
    /// <returns>返回泛型的名字</returns>
    public string GetTName()
    {
        return typeof(T).Name;
    }
}

program.cs

  • autofac使用RegisterGeneric注入泛型

//原生注册泛型容器元素
builder.Services.AddTransient(typeof(IBaseService<>), typeof(BaseService<>));
//autofacf注入泛型容器元素
builder.Host.ConfigureContainer<ContainerBuilder>(builder => 
        {
            builder.RegisterGeneric(typeof(BaseService<>)).As(typeof(IBaseService<>));
        });

在开发时, 有一个习惯, 假如某个方法出现泛型类型, 就要在其下面写一个获取这个泛型的名称的方法

public class MyFactory
{
    public string SetFactory<T>()
    {
        return SetFactory(type(T));
    }
    //获取泛型名字
    public string SetFactory(Type type)
    {
        return type.Name;
    }
}

(3)autofac设置三种容器状态

  1. 默认不写为瞬态

  2. InstancePerLifetimeScope() 线程

  3. .SingleInstance()单例

//单例
builder.RegisterType<UserService>().As<IUserService>().SingleInstance();
       
//瞬态
builder.RegisterType<TransientService>().As<ITransientService>();
​
//线程
builder.RegisterType<SingletonService>().As<ISingletonService>().SingleInstance();
        builder.RegisterType<ScopedService>().As<IScopedService>().InstancePerLifetimeScope();

(4)通过属性注入

1.开启属性注入
  • .PropertiesAutowired(), 代表允许这个类中使用属性注入, 而不是代表这个类被属性注入

//使用autofac容器, 开启属性注入
builder.Host.ConfigureContainer<ContainerBuilder>(builder => 
        {
            builder.RegisterType<Service1>().As<IService1>().PropertiesAutowired();
            builder.RegisterType<Service2>().As<IService2>();
        });
  • 使用属性注入如下

public class Service1 : IService1
{
    public Service2 Service2 { get; set; }
}

(4)扩展方法封装Program.cs

builder.Host.ConfigureContainer<ContainerBuilder>(builder =>
{
    builder.AddSecondDemoApiModel();
});
public static class AutofacExtentions
{
    //扩展方法封装
    public static void AddSecondDemoApiModel(this ContainerBuilder builder)
    {
        builder.RegisterType<UserService>().As<IUserService>().SingleInstance();
        builder.RegisterType<TransientService>().As<ITransientService>();
        builder.RegisterType<SingletonService>().As<ISingletonService>().SingleInstance();
        builder.RegisterType<ScopedService>().As<IScopedService>().InstancePerLifetimeScope();
    }
}