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

如何在非组件的自定义类中使用依赖注入(DI)?

在Blazor非组件类中使用依赖注入的解决方案

核心思路

非组件类无法直接使用@inject或[Inject]特性,必须通过依赖链传递注入或手动从服务容器获取两种方式使用DI,以下是具体实现方案:


方法一:构造函数注入(推荐,符合DI设计原则)

通过构造函数将依赖的服务从上层调用者传递进来,形成完整的依赖链,这是DI的标准用法。

示例场景:自定义业务类调用已注册的JsInteropForClasses

  1. 定义需要依赖注入的业务类,通过构造函数接收JsInteropForClasses:
public class MyBusinessLogic
{
    private readonly JsInteropForClasses _jsInterop;

    // 构造函数注入依赖服务
    public MyBusinessLogic(JsInteropForClasses jsInterop)
    {
        _jsInterop = jsInterop;
    }

    public async Task ExecuteBusinessAction()
    {
        // 直接使用注入的服务实例
        await _jsInterop.MessageBox();
    }
}
  1. 在Program.cs中注册这个业务类(生命周期和JsInteropForClasses保持一致即可):
builder.Services.AddTransient<MyBusinessLogic>();
  1. 在组件中调用时,直接注入业务类即可,Blazor会自动解析整个依赖链:
@inject MyBusinessLogic BusinessService

<button @onclick="ExecuteAction">触发JS弹窗</button>

@code {
    private async Task ExecuteAction()
    {
        await BusinessService.ExecuteBusinessAction();
    }
}

方法二:手动从服务容器获取(仅应急场景使用)

如果遇到无法通过构造函数传递依赖的特殊场景(如静态方法、遗留代码),可以手动从IServiceProvider中获取服务,但这种方式会破坏DI的封装性,不推荐常规使用。

示例实现:

  1. 确保JsInteropForClasses已在Program.cs中注册。
  2. 在需要使用的地方,先注入IServiceProvider(组件中可直接注入),再创建作用域获取服务:
@inject IServiceProvider ServiceProvider

<button @onclick="CallJsDirectly">直接调用JS弹窗</button>

@code {
    private async Task CallJsDirectly()
    {
        // 创建作用域,避免生命周期不匹配问题
        using var scope = ServiceProvider.CreateScope();
        var jsInterop = scope.ServiceProvider.GetRequiredService<JsInteropForClasses>();
        await jsInterop.MessageBox();
    }
}

如果是在非组件类中使用,需要先将IServiceProvider通过构造函数注入到该类中,再执行上述获取逻辑。


额外优化建议

你的MessageBox方法使用了async void,在Blazor中建议替换为async Task,避免异步操作引发的潜在问题:

public async Task MessageBox()
{
    await jSRuntime.InvokeVoidAsync("MessageBox", "DI question!!!");
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 12:30:55