注入IStringLocalizer到BooleanState类时出现NULL,如何正确注入服务?
问题原因
[Inject]属性注入仅在Blazor框架负责实例化的对象(如组件、已注册的服务类)中生效。你通过new BooleanState(true)手动创建实例时,Blazor不会自动注入IStringLocalizer<App>,导致localizer为null;同时静态成员List的初始化时机早于依赖注入容器的准备完成时间,也无法获取有效服务实例。
解决方案
1. 构造函数注入+服务提供者模式(推荐,适合复用场景)
第一步:修改BooleanState类,改用构造函数注入
public class BooleanState { public bool Value { get; set; } public string DisplayText { get; set; } // 通过构造函数注入本地化服务 public BooleanState(bool value, IStringLocalizer<App> localizer) { Value = value; DisplayText = value ? localizer["Yes"] : localizer["No"]; } // 保留自定义显示文本的构造函数 public BooleanState(bool value, string displayText) { Value = value; DisplayText = displayText; } }
第二步:创建状态提供服务
public class BooleanStateProvider { private readonly IStringLocalizer<App> _localizer; private IReadOnlyList<BooleanState> _stateList; public BooleanStateProvider(IStringLocalizer<App> localizer) { _localizer = localizer; } // 懒加载状态列表,确保仅初始化一次 public IReadOnlyList<BooleanState> List => _stateList ??= new[] { new BooleanState(true, _localizer), new BooleanState(false, _localizer) }; }
第三步:注册服务到依赖注入容器
在Program.cs中添加服务注册:
builder.Services.AddScoped<BooleanStateProvider>();
第四步:在Razor页面中使用
@inject BooleanStateProvider StateProvider @foreach (var state in StateProvider.List) { <div>@state.DisplayText</div> }
2. 直接在Razor页面中处理(适合简单场景)
如果不需要跨页面复用状态列表,可直接在页面内注入本地化服务并创建实例:
@inject IStringLocalizer<App> Localizer @{ var booleanStates = new List<BooleanState> { new BooleanState(true, Localizer["Yes"]), new BooleanState(false, Localizer["No"]) }; } @foreach (var state in booleanStates) { <div>@state.DisplayText</div> }
3. 关键注意事项
- 禁止在静态成员中直接依赖需要注入的服务,静态成员初始化时机早于依赖注入容器就绪时间,无法获取有效实例。
- 优先使用构造函数注入而非属性注入,构造注入能确保依赖在对象创建时就已就绪,避免null引用问题。
内容的提问来源于stack exchange,提问作者Ivan-Mark Debono
相关产品推荐
相关产品推荐

