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

如何获取Blazor App中BlazorWebView已有的Scoped实例?

获取BlazorWebView中Blazor App的Scoped服务实例

核心原因

Scoped服务在Blazor中是与组件渲染上下文绑定的,BlazorWebView的根Services容器是全局根容器,直接调用GetService<MyClass>()会创建新的作用域实例,而非Blazor内部正在使用的那个。

解决方案

方法1:通过Singleton代理持有Scoped实例

创建一个Singleton的"持有者"服务,让Blazor组件初始化时把Scoped实例注入进去,原生端通过这个持有者获取实例:

  1. 定义持有者类:
public class MyClassHolder
{
    public MyClass Instance { get; set; }
}
  1. 注册服务:
// 注册为Singleton,确保全局唯一
serviceCollection.AddSingleton<MyClassHolder>();
// 保持MyClass的Scoped注册
serviceCollection.AddScoped<MyClass>();
  1. 在Blazor根组件(如MainLayout.razor)中赋值:
@inject MyClass MyClassInstance
@inject MyClassHolder Holder

@code {
    protected override void OnInitialized()
    {
        // 将Blazor内部的Scoped实例赋值给持有者
        Holder.Instance = MyClassInstance;
    }
}
  1. 原生端获取实例:
var holder = blazorWebView.Services.GetService<MyClassHolder>();
var targetInstance = holder?.Instance;
// 注意:需确保Blazor组件已完成初始化,否则Instance可能为null

方法2:共享作用域容器

创建一个共享的作用域,让BlazorWebView和原生端共用这个作用域的服务容器,这样两边获取的Scoped实例是同一个:

  1. 创建并绑定共享作用域:
// 构建根服务提供者并创建共享作用域
var rootProvider = serviceCollection.BuildServiceProvider();
var sharedScope = rootProvider.CreateScope();

// 让BlazorWebView使用这个共享作用域的服务容器
blazorWebView.Services = sharedScope.ServiceProvider;
  1. 原生端从共享作用域获取实例:
var myClassInstance = sharedScope.ServiceProvider.GetService<MyClass>();
  1. 注意事项:
  • 需在BlazorWebView销毁时释放作用域,避免内存泄漏:
    // 比如在MAUI的页面销毁事件中
    protected override void OnDisappearing()
    {
        sharedScope.Dispose();
        base.OnDisappearing();
    }
    

方法3:通过JS互操作传递实例数据

如果只需要获取Scoped实例的业务数据而非直接操作实例,可以通过Blazor的JS互操作把数据传递到原生端:

  1. 在Blazor组件中注入IJSRuntime和MyClass,调用原生方法传递数据:
@inject IJSRuntime JSRuntime
@inject MyClass MyClassInstance

@code {
    protected override async Task OnInitializedAsync()
    {
        // 将MyClass的属性数据传递给原生端
        await JSRuntime.InvokeVoidAsync("sendMyClassData", 
            MyClassInstance.Property1, 
            MyClassInstance.Property2);
    }
}
  1. 在原生项目中注册JS回调(以MAUI为例):
// 在BlazorWebView初始化时注册JS函数
blazorWebView.JSInitializers.Add("sendMyClassData", 
    (sender, args) => {
        var property1 = args[0].ToString();
        var property2 = args[1].ToString();
        // 处理接收到的数据
    });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 19:31:06