Rob*_*III 2 c# dependency-injection .net-core asp.net-core-webapi
我已经实现了一个自定义的InputFormatter(MyInputFormatter
):
public class MyInputFormatter : SystemTextJsonInputFormatter
{
private readonly IMyDepenency _mydependency;
public CustomInputFormatter(
JsonOptions options,
ILogger<SystemTextJsonInputFormatter> logger,
IMyDependency myDependency
) : base(options, logger)
{
_mydependency = myDependency ?? throw new ArgumentNullException(nameof(myDependency));
}
public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context)
{
//...
}
}
Run Code Online (Sandbox Code Playgroud)
现在,根据文档我需要按如下方式使用它:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(options =>
{
options.InputFormatters.Insert(0, new MyInputFormatter(...));
});
}
Run Code Online (Sandbox Code Playgroud)
但是,正如您所看到的,我CustomInputFormatter
需要一些构造函数参数并且需要一些服务,但我不清楚如何使用 DI 来解析这些服务。我已经阅读了很多像这样的答案/博客/页面,但是输入格式化程序没有任何构造函数参数(因此不需要 DI,只需内联新建一个新实例)或者建议以下内容:
public void ConfigureServices(IServiceCollection services)
{
var sp = services.BuildServiceProvider();
services.AddControllers(options =>
{
options.InputFormatters.Insert(0, new MyInputFormatter(
sp.GetService<...>(),
sp.GetService<...>(),
sp.GetService<IMyDependency>(),
));
});
}
Run Code Online (Sandbox Code Playgroud)
但我们不应该BuildServiceProvider
从打电话ConfigureServices
。
我该怎么办呢?
您可以利用选项基础结构并创建一个IConfigureOptions<MvcOptions>
. 这项新服务可以承受必要的依赖。它将在第一次(MVC 基础设施)请求时被实例化并“执行”IOptions<MvcOptions>
public class ConfigureMvcOptionsFormatters : IConfigureOptions<MvcOptions>
{
private readonly ILoggerFactory _factory;
private readonly JsonOptions _jsonOpts;
private readonly IMyDependency _depend;
public ConfigureMvcOptionsFormatters(IOptions<JsonOptions> options, ILoggerFactory loggerFactory, IMyDependency myDependency)
{
_factory = loggerFactory;
_jsonOpts = options.Value;
_depend = myDependency;
}
public void Configure(MvcOptions options)
{
var logger = _factory.CreateLogger<SystemTextJsonInputFormatter>();
var formatter = new MyInputFormatter(_jsonOpts, logger, _depend);
options.InputFormatters.Insert(0, formatter);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以通过调用以下扩展方法来注册您的类以运行其IConfigureOptions
实现:ConfigureOptions<T>()
IServiceCollection
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.ConfigureOptions<ConfigureMvcOptionsFormatters>();
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用选项构建器及其Configure
回调,将您的依赖项指定为通用参数。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddOptions<MvcOptions>()
.Configure<IOptions<JsonOptions>, ILoggerFactory, IMyDependency>(
(o, j, l, d) => o.InputFormatters.Insert(0, new MyInputFormatter(j.Value, l.CreateLogger<SystemTextJsonInputFormatter>(), d)
);
}
Run Code Online (Sandbox Code Playgroud)
注意:我一直在使用,ILoggerFactory
因为我不相信基础设施会将其注入ILogger<ClassA>
到ClassB
. 不过,我承认我从未尝试过,也没有靠近计算机进行验证。如果确实允许,您可以直接指定您需要的类型。
归档时间: |
|
查看次数: |
1252 次 |
最近记录: |