簡體   English   中英

Asp.Net Core Dependency Injection ValidateOnBuild 無法正常工作

[英]Asp.Net Core Dependency Injection ValidateOnBuild not works properly

我在 .NET 5 中有一個帶有 RazorPages 的項目,我設置了這個代碼來驗證 Progam.cs 文件中的依賴注入:

public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseDefaultServiceProvider(options =>
            {
                options.ValidateOnBuild = true;
                options.ValidateScopes = true;
            })....

我忘記注冊注入到我的頁面中的服務,所以我希望當我嘗試啟動應用程序時,錯誤頁面會顯示這種問題,但我不明白為什么它不會發生,因為例如,如果我沒有注冊 ILocalizerService,就會發生這種情況:這是我的 RazorPage:

public class SignupModel : IdentityPageModel
{
    [BindProperty]
    public Models.Account.Signup Signup { get; set; }

    private readonly CustomUserManager _userManager;
    private readonly ILogger<SignupModel> _logger;
    private readonly INcsService _ncsService;

    public SignupModel(CustomUserManager userManager, 
        ILogger<SignupModel> logger,
        INcsService ncsService) : base(localizerService)
    {
        Guard.Against.Null(userManager, nameof(userManager));

        Guard.Against.Null(logger, nameof(logger));
        Guard.Against.Null(ncsService, nameof(ncsService));
        
        _userManager = userManager;
        _logger = logger;
        _ncsService = ncsService;
    }

    // Other code....
}

這是我的服務:

[PublicAPI]
public class NcsService : INcsService
{
    private readonly IHttpClientFactory _httpClientFactory;

    public NcsService(IHttpClientFactory httpClientFactory)
    {
        _httpClientFactory = httpClientFactory;
    }

    // Other code...
}

我只注冊了 IHttpClientFactory 但沒有注冊 INcsService 接口和實現:

services.AddHttpClient(nameof(NcsService), client =>
{
    client.BaseAddress = new Uri(ncsSettings.BaseUri);
    client.DefaultRequestHeaders.Add("x-functions-key", ncsSettings.ApiKey);
    client.DefaultRequestHeaders.Add("x-app-name", "TSID");

}).AddHeaderPropagation(options =>
{
    options.Headers.Add("x-request-id");
    options.Headers.Add("x-correlation-id");
})
.AddPolicyHandler(GetRetryPolicy());

我希望我很清楚。
謝謝

問題的根源在於 Microsoft 的默認IComponentActivator實現( DefaultComponentActivator )。 組件激活器控制創建 Razor 頁面,但內置行為不會從內置容器請求這些頁面。 相反,它只是使用 Activator.CreateInstance創建它們。

這意味着 Blazor不會在內置容器中注冊您的頁面,因此,該頁面不會成為容器驗證過程的一部分。

這是,IMO,Blazor 中的一個設計缺陷,因為眾所周知,並且很好理解,如果您使用的是 DI 容器,您應該讓所有應用程序組件 go 通過容器管道。 這是容器可以為您提供關於應用程序組件有效性的合理確定性的唯一方法。

然而,Blazor 並不是 ASP.NET 核心框架中發生這種情況的唯一部分。 例如,ASP.NET MVC 控制器默認情況下不會在容器中注冊,也不會從容器中解析。 雖然這是可配置的,但由於這不是默認行為, ValidateOnBuild給人一種錯誤的安全感。

其他容器可能有更合理的默認值。 例如,Simple Injector(我維護的容器)包含總是預先注冊所有 MVC 控制器的擴展方法。 而通過 Blazor 集成,也會發生類似的事情

如果您堅持使用內置容器,最好確保從容器中解析所有組件。 使用 MVC 這很容易,因為您可以簡單地調用AddControllersAsServices 不幸的是,對於 Blazor,這要困難得多,因為不存在AddComponentsAsServices這樣的方法。 這意味着您必須創建一個回調到容器中的自定義IComponentActivator 但是,您仍然可能不得不對 Microsoft 創建的所有 Blazor 組件使用Activator.CreateInstance回退到原始行為,因為使用反射可能更難找到和注冊它們。 有關如何創建此類自定義組件激活器和注冊您的應用程序 Blazor 組件的靈感,請查看此處提供的代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM