Blazor .NET Core如何在@code中访问@Inject注入的IOptions变量?
解决Blazor组件中无法用注入的配置初始化ViewModel的问题
嘿,这是个Blazor新手常碰到的小坑,我来帮你理清楚问题和解决办法!
问题根源
你现在的写法有个关键问题:字段初始化器(也就是直接写private ViewModel _m = new ViewModel(Configuration.Value);的地方)会在组件构造函数执行时运行,但Blazor的依赖注入是在组件构造完成之后,才会把注入的服务赋值给Configuration变量。这时候Configuration还是null,自然会报错。
解决方案一:用组件生命周期方法初始化
最简单的调整方式,是把ViewModel的初始化逻辑移到组件的生命周期方法里,比如OnInitialized或者OnInitializedAsync——这时候注入的配置已经被正确赋值,完全可以安全使用:
@inject IOptions<Configuration> ConfigOptions @* 建议在_Imports.razor里添加@using Microsoft.Extensions.Options; 就能省略完整命名空间 *@ @code { private ViewModel _m; protected override void OnInitialized() { // 此时ConfigOptions已经被DI赋值,可安全访问Value属性 _m = new ViewModel(ConfigOptions.Value); } protected async Task DoSearchAsync() { await _m.PerformSearchAsync(); } }
解决方案二:让ViewModel通过依赖注入自动获取配置(更推荐)
既然你的ViewModel需要接收IOptions<Configuration>,那不如直接把ViewModel注册为服务,让DI自动帮你完成依赖传递,这更符合Blazor的最佳实践:
- 注册ViewModel为服务
在Program.cs的ConfigureServices(或者老版本的Startup.cs)里添加:
// 每个组件实例会获得独立的ViewModel实例 services.AddTransient<ViewModel>(); // 如果希望同一组件生命周期内共用一个ViewModel,可用AddScoped // services.AddScoped<ViewModel>();
- 在组件里直接注入ViewModel
不用手动new,直接把ViewModel注入到组件中:
@inject ViewModel _m @code { protected async Task DoSearchAsync() { await _m.PerformSearchAsync(); } }
- 确保ViewModel构造函数正确接收依赖
你的ViewModel构造函数要写成接收IOptions<Configuration>的形式,DI会自动把对应实例传进来:
public class ViewModel { private readonly Configuration _config; public ViewModel(IOptions<Configuration> configOptions) { _config = configOptions.Value; } public async Task PerformSearchAsync() { // 这里就能正常使用_config.ServiceEndpointUrl了 } }
额外小提示
你的Configuration类里的ServiceEndpointUrl是private属性,ViewModel根本访问不到它,记得改成public:
public class Configuration { public string ServiceEndpointUrl { get; set; } }
内容的提问来源于stack exchange,提问作者User
相关产品推荐
相关产品推荐

