C# Asp.Net核心依赖项注入ValidateOnBuild无法正常工作
我在.NET 5中有一个带有RazorPages的项目,我将此代码设置为验证Progam.cs文件中的依赖注入:C# Asp.Net核心依赖项注入ValidateOnBuild无法正常工作,c#,asp.net-core,dependency-injection,.net-5,C#,Asp.net Core,Dependency Injection,.net 5,我在.NET 5中有一个带有RazorPages的项目,我将此代码设置为验证Progam.cs文件中的依赖注入: public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .UseDefaultServiceProvider(options => { opti
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseDefaultServiceProvider(options =>
{
options.ValidateOnBuild = true;
options.ValidateScopes = true;
})....
我忘了注册注入我页面的服务,所以我本以为当我尝试启动应用程序时,错误页面会显示这种问题,但我不明白为什么不会发生,因为例如,如果我没有注册ILocalizerService,就会发生这种情况:
这是我的照片:
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....
}
我只注册了IHttpClientFactory,但未在服务接口和实现中注册:
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
实现(The)。组件激活器可以控制创建Razor页面,但内置行为不会从内置容器请求这些页面。相反,它只是创造了它们
这意味着Blazor不会在内置容器中注册您的页面,因此该页面不会成为容器验证过程的一部分
在我看来,这是Blazor中的一个设计缺陷,因为众所周知,并且很清楚,如果您使用的是DI容器,那么您应该让所有应用程序组件通过容器管道。这是容器能够为您的应用程序组件的有效性提供合理确定性的唯一方法
然而,Blazor并不是ASP.NET核心框架中发生这种情况的唯一部分。例如,默认情况下,ASP.NET MVC控制器不会在容器中注册,也不会从容器中解析。虽然这是可配置的,但由于这不是默认行为,ValidateOnBuild
提供了错误的安全感
其他容器可能有一个更合理的默认值。例如,SimpleInjector(我维护的容器)包含始终预先注册所有MVC控制器的扩展方法。随着Blazor集成的出现
如果您坚持使用内置容器,那么最好确保从容器解析所有组件。有了MVC,这很容易,因为您只需调用
addControllerAsservices
。不幸的是,对于Blazor,这要困难得多,因为不存在像addComponentsAServices
这样的方法。这意味着您必须创建一个自定义的IComponentActivator
,它将回调到容器中。但是,对于所有由Microsoft创建的Blazor组件,您可能必须使用Activator.CreateInstance
退回到原始行为,因为使用反射查找和注册它们可能会困难得多。有关如何创建此类自定义组件激活器和注册应用程序Blazor组件的灵感,请看下面的代码。嗨,Steven,首先感谢您的回答,实际上我的不是Blazor应用程序,而是一个带有RazorPages的简单应用程序,我相信正如您所指定的,它是基于“MVC”的。我一直在使用SimpleInjector,我很清楚它的验证功能,不幸的是,我仍然不喜欢的是,目前不可能将Microsoft容器完全替换为it@pampua84. 简单喷油器永远不会取代内置容器。它将永远生活在一起。
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());