You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure Function依赖注入报非静态方法需对象引用错误求解

问题根因

两个核心使用错误导致报错:

  1. ElOverblikToken是需要注入配置依赖的类型,你既没有将其注册到Azure Function的DI容器,也没有将其注入到目标函数类的构造函数中,直接以静态调用的方式访问非静态方法,触发非静态方法需要对象引用的错误。
  2. 你尝试将GetToken改为静态方法修复上述错误,但静态方法无法访问类型中定义的非静态实例字段_eloverblikAccess,因此触发第二个对象引用错误——静态方法不绑定到类的任何实例,自然无法访问仅在实例化后才存在的依赖字段。
修复步骤
  • 第一步:安装依赖、配置DI启动类
    先给Azure Function项目安装NuGet包Microsoft.Azure.Functions.Extensions,然后在项目根目录添加Startup.cs完成服务注册,注意将命名空间替换为你自己的项目实际命名空间:
    using Microsoft.Azure.Functions.Extensions.DependencyInjection;
    using Microsoft.Extensions.DependencyInjection;
    
    [assembly: FunctionsStartup(typeof(YourProjectNamespace.Startup))]
    namespace YourProjectNamespace
    {
        public class Startup : FunctionsStartup
        {
            public override void Configure(IFunctionsHostBuilder builder)
            {
                // 绑定配置类
                builder.Services.AddOptions<ConnectionSettings>()
                    .Bind(builder.GetContext().Configuration.GetSection("ConnectionSettings"));
                builder.Services.AddOptions<ELoverblikAccess>()
                    .Bind(builder.GetContext().Configuration.GetSection("ELoverblikAccess"));
                // 注册Token服务,生命周期可根据需求选Transient/Scoped
                builder.Services.AddTransient<ElOverblikToken>();
            }
        }
    }
    
  • 第二步:修改Function类,注入ElOverblikToken实例
    不要直接用类名静态调用方法,把需要的服务通过构造函数注入后,调用实例方法:
    public class GetEloverblik
    {
        private readonly ConnectionSettings _connectionSettings;
        private readonly ELoverblikAccess _eloverblikAccess;
        private readonly ElOverblikToken _elOverblikToken;
    
        public GetEloverblik(
            IOptions<ConnectionSettings> connectionStrings, 
            IOptions<ELoverblikAccess> eloverblikAccess,
            ElOverblikToken elOverblikToken)
        {
            _connectionSettings = connectionStrings?.Value ?? throw new ArgumentNullException(nameof(connectionStrings));
            _eloverblikAccess = eloverblikAccess?.Value ?? throw new ArgumentNullException(nameof(eloverblikAccess));
            _elOverblikToken = elOverblikToken ?? throw new ArgumentNullException(nameof(elOverblikToken));
        }
    
        [FunctionName("GetEloverblik")]
        public async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req, ILogger log)
        {
            try
            {
                // 调用注入实例的方法
                string token = await _elOverblikToken.GetToken();
            }
            catch (Exception ex)
            {
                log.LogInformation(ex.Message);
            }
            return new OkObjectResult("Done");
        }
    }
    
  • 第三步:修正ElOverblikToken类,移除方法的static修饰符
    该类由DI容器负责实例化,构造函数注入的依赖只能被实例方法访问,不要使用静态方法:
    public class ElOverblikToken    
    {
        private readonly ELoverblikAccess _eloverblikAccess;
        private readonly ConnectionSettings _connectionSettings;
    
        public ElOverblikToken(IOptions<ConnectionSettings> connectionStrings, IOptions<ELoverblikAccess> eloverblikAccess)
        {            
            _connectionSettings = connectionStrings?.Value ?? throw new ArgumentNullException(nameof(connectionStrings));
            _eloverblikAccess = eloverblikAccess?.Value ?? throw new ArgumentNullException(nameof(eloverblikAccess));
        }
    
        // 保持为实例方法,不要加static
        public async Task<string> GetToken()
        {
            try
            {
                // 业务逻辑,可正常访问两个注入的配置字段
                return token;
            }
            catch (Exception ex)
            {
                return null;
            }
        }
    }
    
注意事项

依赖注入的核心原则是:所有需要依赖其他服务、配置的类型,统一交给DI容器管理生命周期,不要手动new、不要随意用静态调用。需要使用某个服务时,直接在构造函数声明对应类型的参数,容器会自动按注册顺序传入依赖。
静态类、静态方法天生不适配依赖注入模式,静态成员是进程全局共享的,无法按照DI的生命周期规则注入实例级依赖。

内容的提问来源于stack exchange,提问作者SqlKindaGuy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 00:18:20