如何在 Maui Blazor 中共享 Maui 服务和 Blazor 服务的 ServiceProvider

Jea*_*ean 1 c# blazor maui maui-blazor

我正在尝试弄清楚如何在 MauiBlazor 项目中共享 Maui 和 Blazor 之间的服务。目标是能够使用相同的单例,而无需在某处存储这些单例的静态实例。

Jea*_*ean 6

虽然在未来的版本中这可能是一种更方便的方法,但我从Maui.Plugins.PageResolver的一些灵感中找到了一种方法。相关问题maui#792

我在 Github 上添加了一个nuget + 工作示例应用程序

我是这样解决的:

1. 为服务提供者创建存储库

public static class Resolver
{
    private static IServiceProvider _serviceProvider;
    public static IServiceProvider ServiceProvider => _serviceProvider ?? throw new Exception("Service provider has not been initialized");

    /// <summary>
    /// Register the service provider
    /// </summary>
    public static void RegisterServiceProvider(IServiceProvider sp)
    {
        _serviceProvider = sp;
    }
    /// <summary>
    /// Get service of type <typeparamref name="T"/> from the service provider.
    /// </summary>
    public static T Resolve<T>() where T : class
        => ServiceProvider.GetRequiredService<T>();
}
Run Code Online (Sandbox Code Playgroud)

2、app启动的扩展方法

public static void UseResolver(this MauiApp app)
{
    Resolver.RegisterServiceProvider(app.Services);
}

Run Code Online (Sandbox Code Playgroud)

或者避免对毛伊岛的依赖:

public static void UseResolver(this IServiceProvider sp)
{
    Resolver.RegisterServiceProvider(sp);
}
Run Code Online (Sandbox Code Playgroud)

3a. 样品测试服务

public class TestSingletonService
{
    private static int _staticIndex = 0;
    public int Index {  get; set; }

    public TestSingletonService()
    {
        Index = _staticIndex++;
    }
}
Run Code Online (Sandbox Code Playgroud)

3b. 注册服务集合

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .RegisterBlazorMauiWebView()
            .UseMauiApp<App>()
            .ConfigureFonts(fonts =>
            {
                fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
            });

        builder.Services.AddBlazorWebView();
        builder.Services.AddSingleton<WeatherForecastService>();

        // Register any other service / ViewModel / Page here
        builder.Services.AddSingleton<TestSingletonService>();

        // Pre-build the app
        var app = builder.Build();
        // Intercept and register the ServiceProvider
        app.UseResolver();
        // Or to avoid Maui dependency
        // app.Services.UseResolver();
        // Return the app as usual
        return app;
    }
}
Run Code Online (Sandbox Code Playgroud)

4a. 将其用作毛伊岛一侧的工厂

public static class Resolver
{
    private static IServiceProvider _serviceProvider;
    public static IServiceProvider ServiceProvider => _serviceProvider ?? throw new Exception("Service provider has not been initialized");

    /// <summary>
    /// Register the service provider
    /// </summary>
    public static void RegisterServiceProvider(IServiceProvider sp)
    {
        _serviceProvider = sp;
    }
    /// <summary>
    /// Get service of type <typeparamref name="T"/> from the service provider.
    /// </summary>
    public static T Resolve<T>() where T : class
        => ServiceProvider.GetRequiredService<T>();
}
Run Code Online (Sandbox Code Playgroud)

4b. 这些服务实例将与您的 Blazor 服务共享@inject

@inject TestSingletonService tester
Instance number @(tester.Index).
Run Code Online (Sandbox Code Playgroud)