Azure Function依赖注入报非静态方法需对象引用错误求解
问题根因
两个核心使用错误导致报错:
ElOverblikToken是需要注入配置依赖的类型,你既没有将其注册到Azure Function的DI容器,也没有将其注入到目标函数类的构造函数中,直接以静态调用的方式访问非静态方法,触发非静态方法需要对象引用的错误。- 你尝试将
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
相关产品推荐
相关产品推荐

