添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

修改 Program 类

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseServiceProviderFactory(new AutofacServiceProviderFactory())
            .ConfigureWebHostDefaults(webBuilder =>
                webBuilder.UseStartup<Startup>();
  • 修改 Startup 类,在该类中添加 ConfigureContainer 方法
  • 属性介绍:
    RegisterAssemblyTypes:寄存器程序集类型
    AsImplementedInterfaces:实现的接口
    InstancePerDependency:实例依赖关系
    PropertiesAutowired:属性自动连接(属性自动注入)

            /// <summary>
            /// 配置Autofac容器替换微软的DI
            /// </summary>
            /// <param name="containerBuilder"></param>
            public void ConfigureContainer(ContainerBuilder builder)
                // 单个服务类注册
                builder.RegisterType<UserService>().As<IUserService>().InstancePerLifetimeScope();
                // 多个服务类,也就是程序集注册 //
                // 这是注册其他项目的程序集服务
                var basePath = AppContext.BaseDirectory;
                //DALService所在程序集命名空间
                string DALPath = Path.Combine(basePath, "GraduationProject.DAL.dll");
                Assembly DAL = Assembly.LoadFrom(DALPath);
                //BLLService所在程序集命名空间
                string BLLPath = Path.Combine(basePath, "GraduationProject.BLL.dll");
                Assembly BLL = Assembly.LoadFrom(BLLPath);
                builder.RegisterAssemblyTypes(DAL).InstancePerDependency().PropertiesAutowired();
                builder.RegisterAssemblyTypes(BLL).AsImplementedInterfaces().InstancePerDependency().PropertiesAutowired();
                // 这是注册同一项目下的程序集服务
                builder.RegisterAssemblyTypes(typeof(Program).Assembly)
                .Where(t => t.Name.EndsWith("Service"))
                .AsImplementedInterfaces()
                .InstancePerLifetimeScope();
    

    或者新建AutofacModelRegister 配置类

    // 继承自 Autofac.Model    
    public class AutofacModelRegister : Autofac.Module
          //重写Autofac管道Load方法,在这里注册注入
         protected override void Load(ContainerBuilder builder)
             // 配置逻辑同上
             builder.RegisterType<UserService>().As<IUserService>();
    
    // 然后在startup类中新建ConfigureContainer方法,配置
    public void ConfigureContainer(ContainerBuilder builder)
        // 直接用Autofac注册我们自定义的 
        builder.RegisterModule(new AutofacModuleRegister());
        // 服务项目程序集
        //Assembly service = Assembly.Load("XXX.Service");
        // 服务接口项目程序集
        //Assembly iservice = Assembly.Load("XXX.IService");
        //builder.RegisterAssemblyTypes(service, iservice).Where(t => t.FullName.EndsWith("Service") && !t.IsAbstract)
        //.InstancePerLifetimeScope()
        //.AsImplementedInterfaces();
    

    注意:如果需要注入的服务没有 interface ,那么 builder.RegisterAssemblyTypes 就只需要传一个程序集就OK了。如果服务与接口同在一个项目,那也是要传两个程序集的哦。

    controller 中使用

    [ApiController]
    [Route("[controller]")]
    public class HomeController : ControllerBase
        private readonly IUserService _userService;
        public HomeController(IUserService userService)
            _userService = userService;
        [HttpGet]
        public IActionResult Index()
            return Ok(_userService.GetName("Test"));
    

    属性自动注入

    默认支持构造函数注入,如果需要属性注入,对比构造函数注入,属性注入就多追加了 PropertiesAutowired() 函数
    在这里插入图片描述

    注意:属性注入记得将属性的访问修饰符改为注册类可访问的修饰符,否则会注入失败。
    在这里插入图片描述

    如果不是public 则会抛出空引用。
    原因大概就是 Controller 是由 Mvc 模块管理的,不在 IOC 容器内,所以在 Controller 中无法使用 Autofac 注入的实例。

    // 解决上面的问题,在 Startup 的 ConfigureServices 方法底部加入如下代码:
    // 使用 ServiceBasedControllerActivator 替换 DefaultControllerActivator; // Controller 默认是由 Mvc 模块管理的,不在 Ioc 容器中。替换之后,将放在 Ioc 容器中。 
    services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
    // 然后回到我们的 AutofacModuleRegister 注入 Controller:
    builder.RegisterTypes(GetAssemblyTypes<Startup>(type => typeof(ControllerBase).IsAssignableFrom(type)))                 .PropertiesAutowired();