如何在 Blazor 中仅在服务存在时注入服务?

4

如果我使用Inject属性并尝试注入未注册的服务,则会出现错误没有已注册类型为X的服务

那么如何在不出现此错误的情况下注入服务,如果未注入服务,则该服务将为空。这可能吗?

例如:

如果Foo没有注册,这将给我一个错误。

[Inject]
protected Foo Foo { get; set; }

但我希望允许 Foo 未注册的情况,此时它将成为 null


这显然是一个 XY 问题。详细说明(你认为)你需要它的原因,你可能会得到更好的选择。 - H H
@HenkHolterman 这不是一个 XY 问题,我可以解释为什么我需要这个,但我想知道,你能想到需要可选服务的情况吗? - Vencovsky
在应用程序层面上,我不会允许这样做。在库中可能有一些意义,但我会尽力避免这种情况。 - H H
@HenkHolterman,你差不多就快做对了。它不是一个库,而是我们公司许多使用Blazor的应用程序所共享的内核。我在我的组件中注入了一个“全局加载”服务,以便它可以监视应用程序中任何加载状态的更改,并在需要时设置自己的加载状态。但是我没有考虑到并非所有应用程序都会使用这个“全局加载”。已经有两个应用程序在使用它,但现在将有一个应用程序不会使用它。因此,现在我需要找到一种方法,在组件中继续使用它,但当该服务未实现时不会出现任何错误。 - Vencovsky
这是一个功能请求 - user276648
2个回答

7

你可以做到

@inject IServiceProvider ServiceProvider

@code
{
  private IMyService MyService;

  protected override void OnInitialized()
  {
    MyService = ServiceProvider.GetService<IMyService>();
    base.OnInitialized();
  }
}

0

如果您想要访问服务器端数据,那么这个问题可能是有意义的,但前提是 Blazor 在服务器端进行预渲染(Blazor WebAssembly 应用程序(ASP.Net Core 托管))。

在这种情况下,您可能需要在 ASP.Net 应用程序的 Startup.cs 和 Blazor WebAssembly 入口点 Program.cs 中注册服务。

在这种情况下,您可以为您想要访问的功能创建接口:

namespace BlazorApp1.Client {
    public interface IResponse {
        void SetNotFound();
    }
}

在Program.cs中注册一个什么也不做或返回空结果的接口实例:

namespace BlazorApp1.Client {
    public class ResponseStub : IResponse {
        public void SetNotFound() {
            // Do nothing if we are browser side
        }
    }
}

还有另一个实例,它使用在Setup.cs中设置的实例来完成工作:

using BlazorApp1.Client;
using Microsoft.AspNetCore.Http;
using System.Net;

namespace BlazorApp1.Server {
    public class Response : IResponse {
        private readonly IHttpContextAccessor _httpContextAccessor;

        public Response(IHttpContextAccessor accessor) {
            _httpContextAccessor = accessor;
        }

        public void SetNotFound() {
            _httpContextAccessor.HttpContext.Response.StatusCode = (int)HttpStatusCode.NotFound;
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接