gpt4 book ai didi

c# - 在ConfigureServices中使用DI?

转载 作者:行者123 更新时间:2023-12-02 02:46:01 26 4
gpt4 key购买 nike

我已经实现了一个自定义的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)
{
//...
}
}

现在,根据 the documentation我需要按如下方式使用它:

public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(options =>
{
options.InputFormatters.Insert(0, new MyInputFormatter(...));
});
}

但是,正如您所看到的,我的 CustomInputFormatter 需要一些构造函数参数,并且需要一些服务,但我不清楚如何使用 DI 来解析这些服务。我读过很多答案/博客/页面,例如 this one但要么 inputformatter 没有任何构造函数参数(因此不需要 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>(),
));
});
}

但是我们不应该从 ConfigureServices 调用 BuildServiceProvider

我该如何解决这个问题?

最佳答案

您可以使用Options infrastructure并创建一个 IConfigureOptions<MvcOptions> 。这项新服务可以承受必要的依赖。它将在第一次请求 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);
}
}

然后您注册您的类(class)以获得其 IConfigureOptions通过调用 ConfigureOptions<T>() extension method on the IServiceCollection 运行实现:

public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.ConfigureOptions<ConfigureMvcOptionsFormatters>();
}

或者,您可以将选项构建器与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)
);
}

注意:我一直在使用ILoggerFactory因为我不相信基础设施会注入(inject) ILogger<ClassA>进入ClassB 。不过,我承认我从未尝试过,也没有靠近计算机进行验证。如果确实允许,您可以直接指定您需要的类型。

关于c# - 在ConfigureServices中使用DI?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62793613/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com