.Net Core 3.1 使用Autofac

在ASP.NET Core中,自带的IOC容器相关的使用方式和注入类型的生命周期.

微软给自行注入的服务,提供了3种生命周期.

  • Transient(瞬时的)

    每次请求时都会创建的瞬时生命周期服务。这个生命周期最适合轻量级,无状态的服务。

  • Scoped(作用域的)

    在同作用域,服务每个请求只创建一次。

  • Singleton(唯一的)

    全局只创建一次,第一次被请求的时候被创建,然后就一直使用这一个.

自带的IOC 并不支持AOP(面向切面编程),所以我们最好还是使用Autofac.

  1. 从nuget引用包

    • Autofac
    • Autofac.Extensions.DependencyInjection
  2. 在Program.cs 新增一行代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
    .UseServiceProviderFactory(new AutofacServiceProviderFactory())//使用AutoFac做IOC和AOP

    .ConfigureWebHostDefaults(webBuilder =>
    {
    webBuilder.UseStartup<Startup>();
    webBuilder.UseUrls("http://*:8080");
    });
  3. 在Startup.cs 增加方法

    1
    2
    3
    4
    public void ConfigureContainer(ContainerBuilder containerBuilder)
    {
    containerBuilder.RegisterModule<ConfigureAutofac>();
    }

    ConfigureAutofac 是自己封装的一个类 继承了 Autofac.Module 也可以将以下代码直接写在这个方法里面:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    public class ConfigureAutofac : Module
    {
    protected override void Load(ContainerBuilder containerBuilder)
    {
    //程序集范围注入 名称注入
    var service = Assembly.Load("Services");
    var iService = Assembly.Load("IServices");
    containerBuilder.RegisterAssemblyTypes(service, iService)
    .Where(t => t.Name.EndsWith("Service"))
    .AsImplementedInterfaces().PropertiesAutowired();
    var repository = Assembly.Load("Repository");
    var iRepository = Assembly.Load("IRepository");
    containerBuilder.RegisterAssemblyTypes(repository, iRepository)
    .Where(t => t.Name.EndsWith("Repository"))
    .AsImplementedInterfaces().PropertiesAutowired();

    //注册当前程序集中以“Ser”结尾的类,暴漏类实现的所有接口,生命周期为PerLifetimeScope
    //containerBuilder.RegisterAssemblyTypes(System.Reflection.Assembly.GetExecutingAssembly()).Where(t => t.Name.EndsWith("Service")).AsImplementedInterfaces().InstancePerLifetimeScope();
    //containerBuilder.RegisterAssemblyTypes(System.Reflection.Assembly.GetExecutingAssembly()).Where(t => t.Name.EndsWith("Repository")).AsImplementedInterfaces().InstancePerLifetimeScope();

    //注册所有"Repository"程序集中的类
    //builder.RegisterAssemblyTypes(GetAssembly("Repository")).AsImplementedInterfaces();

    //单个注册
    //containerBuilder.RegisterType<ExpertService>().As<IExpertService>().PropertiesAutowired();

    //在控制器中使用属性依赖注入,其中注入属性必须标注为public
    // var controllersTypesInAssembly = typeof(Startup).Assembly.GetExportedTypes()
    // .Where(type => typeof(Microsoft.AspNetCore.Mvc.ControllerBase).IsAssignableFrom(type)).ToArray();
    //containerBuilder.RegisterTypes(controllersTypesInAssembly).PropertiesAutowired();
    }
    }
  4. 控制器通过构造函数注入,或者属性注入:

    1
    2
    3
    4
    5
    6
    private readonly ITargetService _targetService;
    private IScopeService _scopeService { get; set; }//属性注入
    public ExpertController(ITargetService targetService)
    {
    _targetService = targetService;
    }

    其中属性注入需要在Startup.cs 的 ConfigureServices 方法下加入如下代码:

    services.AddControllers().AddControllersAsServices();

注意: .Net Core 2.x和3.x 使用autofac注入方式不一样,此文仅适用于.Net Core 3.X