Autofac的使用

是IOC容器 支持三种类型DI 配置文件配置映射关系 支持AOP扩展

.Net Core中具体使用步骤

1.导入Nuget包
2. Progam中的CreateHostBuilder方法,使用autofac的容器工厂替换系统默认的容器
public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .UseServiceProviderFactory(new AutofacServiceProviderFactory())//使用autofac的容器工厂替换系统默认的容器
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });
3. 在Startup中增加一个方法ConfigureContainer
public void ConfigureContainer(ContainerBuilder containerBuilder)
{
    //指定服务的注册
    containerBuilder.RegisterType<UserService>().As<IUserService>().InstancePerLifetimeScope().AsImplementedInterfaces();
    containerBuilder.RegisterType<ProductService>().As<IProductService>().InstancePerLifetimeScope().AsImplementedInterfaces();
    var container = containerBuilder.Build();
    IUserService userService = container.Resolve<IUserService>();
    IProductService productService = container.Resolve<IProductService>();
    userService.Show();
    productService.Show();
}

这样写 一看就可以发现 随着接口的增加 我们每次都需要手动在container方法中进行注册 很麻烦 这是我们就可以利用反射 如下

public void ConfigureContainer(ContainerBuilder containerBuilder)
{
    Assembly service = Assembly.Load("AspNetCore.Ioc.Service");
    Assembly iservice = Assembly.Load("AspNetCore.Ioc.Interface");
    containerBuilder.RegisterAssemblyTypes(service, iservice)
    .Where(t => t.FullName.EndsWith("Service") && !t.IsAbstract) //类名以service结尾,且类型不能是抽象的 
        .InstancePerLifetimeScope() //生命周期,,
        .AsImplementedInterfaces()
    .PropertiesAutowired(); //属性注入
}

当遇到一个接口多个现实时 我们也可以指定注册 如下

//一个接口有多个实现:注册所有实现的服务实例
builder.RegisterAssemblyTypes(Assembly.Load("AspNetCore.Ioc.Service")).As<IUserService>();
//一个接口有多个实现:只注册以A结尾的服务实例
builder.RegisterAssemblyTypes(Assembly.Load("AspNetCore.Ioc.Service")).Where(c=>c.Name.EndsWith("A")).As<IUserService>();
//一个接口有多个实现:注册所有实现的服务实例,并排除UserServiceA服务实例
builder.RegisterAssemblyTypes(Assembly.Load("AspNetCore.Ioc.Service")).Except<UserServiceA>().As<IUserService>();

但是随之我们也发现 这样Startup中的代码还是会越来越多
这时我们可以采用自定义AutofacModule的方式进行简化 将服务注册的代码抽离出来 放置在单独的文件中
接下来我们新建一个类 MyAutofacModule类 用于服务注册的处理

using System.Linq;
using System.Reflection;
using Autofac;
using Autofac.Configuration;
using Microsoft.Extensions.Configuration;
namespace AspNetCore.Ioc.Web.Utility
{
    public class MyAutofacModule : Autofac.Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            //反射程序集方式服务注册
            Assembly service = Assembly.Load("AspNetCore.Ioc.Service");
            Assembly iservice = Assembly.Load("AspNetCore.Ioc.Interface");
            builder.RegisterAssemblyTypes(service, iservice)
            .Where(t => t.FullName.EndsWith("Service") && !t.IsAbstract) //类名以service结尾,且类型不能是抽象的 
                .InstancePerLifetimeScope() //作用域生命周期
                .AsImplementedInterfaces()
                .PropertiesAutowired(); //属性注入
        }
    }
}

然后只需要将startup中的ConfigureContainer方法修改一下 如下

public void ConfigureContainer(ContainerBuilder containerBuilder)
{
   containerBuilder.RegisterModule<MyAutofacModule>();
}

就可以了

4. 除了新建注册类 我们还可以通过配置文件 进行注册优化 同时也使服务注册变得更加灵活

配置文件格式如下

{
  "defaultAssembly": "AspNetCore.Ioc.Interface", //接口所在的程序集名称
  "components": [
    {
      "type": "AspNetCore.Ioc.Service.UserService,AspNetCore.Ioc.Service", //接口的实现 全名称
      "services": [
        {
          "type": "AspNetCore.Ioc.Interface.IUserService" // 接口的全名称
        }
      ],
      "instanceScope": "single-instance", //单例生命周期
      "injectProperties": true //是否支持属性注入
    },
    {
      "type": "AspNetCore.Ioc.Service.ProductService,AspNetCore.Ioc.Service", //接口的实现 全名称
      "services": [
        {
          "type": "AspNetCore.Ioc.Interface.IProductService" // 接口的全名称
        }
      ],
      "instanceScope": "single-instance", //单例生命周期
      "injectProperties": true //是否支持属性注入
    }
  ]
}

【注】记得修改配置文件属性-->始终复制
接着再修改MyAutofacModule中的调用方法 如下

protected override void Load(ContainerBuilder builder)
{
    //Autofac 基于配置文件的服务注册
    IConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
    configurationBuilder.AddJsonFile("Config/autofac.json");
    IConfigurationRoot root = configurationBuilder.Build();
    //开始读取配置文件中的内容
    ConfigurationModule module = new ConfigurationModule(root);
    //根据配置文件的内容注册服务
    builder.RegisterModule(module);
}

这样就可以了

posted @ 2021-02-19 16:19  C余L小R鱼  阅读(177)  评论(0编辑  收藏  举报