Asp.Net 动态接口中属性注入未生效的问题解决实用指南

作者:袖梨 2026-09-07

平时做技术实践时,很多问题不是概念不会,而是细节没串起来。拿“Asp.Net 动态接口中属性注入未生效的问题解决”来说,它看着像小点,放到项目里常会牵出环境、配置、兼容性和维护成本。下面按实际采用顺序,把思路、关键写法和容易踩坑的地方讲清楚,便于大家直接对照操作。

目录
  • - 不加AddControllersAsServices()
  • - 加AddControllersAsServices()

理解这一步时,我有一个授权Service【AuthService】继承抽象类【ApplicationService】,程序会后会将所有继承IApplicationService的Service动态转换为Api接口,在swagger采用原生Controller控制器接口调用AuthService是没有问题的,测试【AuthService】的动态接口报错【LazyServiceProvider为null】

容器注入选择的是:Autofac,所有服务均注册

抽象类代码如下所示:

其中LazyServiceProvider是借助属性注入来实现的

    [Authorize]
    public abstract class ApplicationService : IApplicationService, IDynamicApi
    {
        /// <summary>
        /// 懒加载服务驱动(属性注入)
        /// </summary>
        [Autowired]
        public ILazyServiceProvider LazyServiceProvider { get; set; }
        #region Private-Attribute
        private IMapper _ObjectMapper;
        private ICurrentUserService _CurrentUser;
        private IPermissionChecker _IPermissionChecker;
        #endregion Private-Attribute
        #region Protected-Attribute
        /// <summary>
        /// AutoMap
        /// </summary>
        protected IMapper ObjectMapper
        {
            get
            {
                if (_ObjectMapper == null)
                {
                    _ObjectMapper = LazyServiceProvider.LazyGetRequiredService<IMapper>();
                }
                return _ObjectMapper;
            }
        }
        /// <summary>
        /// 当前用户
        /// </summary>
        protected ICurrentUserService CurrentUser
        {
            get
            {
                if (_CurrentUser == null)
                {
                    _CurrentUser = LazyServiceProvider.LazyGetRequiredService<ICurrentUserService>();
                }
                return _CurrentUser;
            }
        }
        /// <summary>
        /// 权限检查
        /// </summary>
        protected IPermissionChecker PermissionChecker
        {
            get
            {
                if (_IPermissionChecker == null)
                {
                    _IPermissionChecker = LazyServiceProvider.LazyGetRequiredService<IPermissionChecker>();
                }
                return _IPermissionChecker;
            }
        }
        #endregion Protected-Attribute
    }

解决方法:

在ASP.NET Core设置中:

builder.Services.AddControllers()
    .AddControllersAsServices(); // 这很重要,确保控制器由DI容器解析

AddControllersAsServices()的主要作用是:

  1. 将控制器注册为服务:将所有控制器类注册到依赖注入(DI)容器中

  2. 采用DI容器解析控制器:确保控制器实例由DI容器新建,而不是由MVC框架直接实例化

加与不加的区别:

- 不加AddControllersAsServices()

  1. 控制器新建方式

    • MVC框架会直接采用 ActivatorUtilities.CreateInstance 新建控制器实例

    • 只兼容构造函数注入,不兼容属性注入

  2. 生命周期

    • 每个请求都会新建新的控制器实例

    • 生命周期完全由MVC框架管理

  3. 限制

    • 无法采用Autofac等第三方容器的高级功能(如属性注入)

    • 无法自定义控制器的解析过程

- 加AddControllersAsServices()

  1. 控制器新建方式

    • 控制器实例由DI容器新建

    • 兼容完整的DI功能,包括构造函数注入和属性注入

  2. 优势

    • 能够采用第三方容器(如Autofac)的所有功能

    • 兼容属性注入

    • 能够自定义控制器的生命周期

    • 能够在控制器解析前后执行自定义逻辑

  3. 生命周期

    • 默认仍然是每个请求新建新实例(Transient)

    • 但能够借助注册时指定来改变生命周期

到此这篇关于Asp.Net 动态接口中属性注入未生效的文章就介绍到这了,更多相关Asp.Net 属性注入未生效内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多兼容脚本之家!

您可能感兴趣的文章:
  • ASP.NET Core 奇淫技巧之伪属性注入的实现

相关文章

精彩推荐