Blazor Server:非页面.cs文件使用注入服务与级联参数是否合法?
关于Blazor中普通类使用[Inject]和[CascadingParameter]的疑问解答
首先明确:[Inject]和[CascadingParameter]这两个特性并不是应用内任意代码都能用的,它们只适用于Blazor的组件类(包括razor组件、razor.cs代码后置类,以及直接继承ComponentBase的类)
为什么你当前的代码能正常运行?
大概率是你的这个普通类刚好处于Blazor组件的生命周期上下文里——比如它是被Blazor组件通过依赖注入实例化的,或者被当作组件的一部分创建,这时候Blazor的组件激活机制会顺带处理这两个特性的赋值。但这属于“偶然生效”的情况,不是通用场景。
这么做的隐患
- 脱离组件上下文就失效:如果哪天你在非Blazor组件的场景中实例化这个类(比如自己用
new创建,或者在后台服务、普通业务类里调用),[Inject]标注的成员会是null,[CascadingParameter]的authenticationStateTask也不会被赋值,直接调用会触发空引用异常。 - [CascadingParameter]逻辑不合理:级联参数是Blazor组件树特有的传递机制,依赖组件树的上下文。普通类不在组件树中,就算偶然拿到值,也无法保证和当前用户的组件上下文一致,容易出现身份信息不匹配的问题。
- 不符合DI最佳实践:对于普通服务/业务类,官方推荐用构造函数注入获取依赖,而不是
[Inject]属性注入。[Inject]是Blazor组件为了简化写法设计的,放到普通类里会破坏DI的明确性,也不利于代码维护和测试。
正确的做法
- 普通类获取依赖:把需要的服务(比如
ILogger<Register>)放到类的构造函数参数中,在Program.cs里注册这个类,之后通过DI容器获取实例,保证依赖能稳定注入。 - 获取AuthenticationState:在普通类中注入
AuthenticationStateProvider,调用它的GetAuthenticationStateAsync()方法获取身份状态,这才是通用的、不依赖组件上下文的方式。 - 组件类专属用法:只有在Blazor组件类(继承
ComponentBase)中,才适合用[Inject]简化依赖注入,用[CascadingParameter]接收组件树传递的参数。
内容的提问来源于stack exchange,提问作者David Thielen
相关产品推荐
相关产品推荐

