我的 Startup
中有以下代码类,它使用 IModelBinderProvider
的自定义实例.大多数输入格式化程序需要 ILogger
例如,所以我需要一个 ILoggerFactory
,为此我想使用配置的,它以指定的详细程度记录到指定的目的地。我正在抢 ILoggerFactory
来自新建 IServiceProvider
:
public void ConfigureServices(IServiceCollection services)
{
...
services.AddMvcCore(
options =>
{
...
var serviceProvider = services.BuildServiceProvider();
var loggerFactory = serviceProvider.GetService<ILoggerFactory>();
options.ModelBinderProviders.Clear();
options.ModelBinderProviders.Add(
new MyCustomBinderProvider(options.InputFormatters, loggerFactory)
);
...
}
);
...
}
问题是我收到以下警告:Startup.cs(62, 43): [ASP0000] Calling 'BuildServiceProvider' from application code results in an
additional copy of singleton services being created. Consider alternatives such
as dependency injecting services as parameters to 'Configure'.
我看了一下这个问题:Resolving instances with ASP.NET Core DI from within ConfigureServices .但是,我的代码是 AddMvcCore
的 lambda ,这是配置 options
目的。换句话说,到时候Configure
被调用,MVC 选项已经定义。有没有办法在这里做正确的事情,即防止
IServiceProvider
的无关实例?
最佳答案
在配置选项时有几种方法可以注入(inject)服务。第一种方法是使用 OptionsBuilder<TOptions>
可以通过使用扩展方法获得IServiceCollection.AddOptions
, 像这样:
services.AddOptions<MvcOptions>()
//first arg is always of TOptions,
//injectable dependencies start from the second arg
.Configure((MvcOptions o, ILoggerFactory loggerFactory) => {
o.ModelBinderProviders.Insert(0,
new MyCustomBinderProvider(o.InputFormatters, loggerFactory)
);
});
第二种方法是通过实现 IConfigureOptions<TOptions>
(或 IPostConfigureOptions<TOptions>
),像这样:public class ConfigureMvcOptions : IConfigureOptions<MvcOptions>
{
readonly ILoggerFactory _loggerFactory;
public ConfigureMvcOptions(ILoggerFactory loggerFactory)
{
_loggerFactory = loggerFactory;
}
public void Configure(MvcOptions options)
{
options.ModelBinderProviders.Insert(0,
new MyCustomBinderProvider(options.InputFormatters, _loggerFactory)
);
}
}
//then configure it like this:
services.ConfigureOptions<ConfigureMvcOptions>();
第一种方法很方便,因为您不必为 IConfigureOptions<Options>
的实现创建单独的类。但它的可注入(inject)依赖项数量有限。第二种方式可以让你注入(inject)任意多,适合大量配置代码。
关于asp.net-mvc - 在没有新的 IServiceProvider 实例的情况下指定自定义 IModelBinderProvider?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66539910/