gpt4 book ai didi

asp.net-core - 如何将依赖注入(inject)与 .NET Core 2 API 选项结合使用?

转载 作者:行者123 更新时间:2023-12-05 05:17:21 26 4
gpt4 key购买 nike

我的启动配置服务中有以下代码:

 services.AddMvc(options => options.RespectBrowserAcceptHeader = true)
.AddXmlDataContractSerializerFormatters()
.AddXmlSerializerFormatters()
.AddJsonOptions(o =>
{
o.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;
});

以及以下模型:

public interface ITestInterface
{
string Hello { get; set; }
}

public class TestInput
{
public string IWork { get; set; }
public ITestInterface IDontWork { get; set; }
}

所以在我的 Controller Action 上:

public async Task<IActionResult> Update([FromBody]TestInput testInput)
{

}

如果我发送以下 JSON:

{
"IWork": "I do work",
"IDontWork": { "Hello": "hi hi" }
}

我正确填充了 IWork,但没有正确填充 IDontWork。但是,我的界面已注册为 transient 服务...我是否需要在 JSON 选项中设置其他内容或使用我自己的契约(Contract)解析器?

最佳答案

However, my interface is registered as a transient service...

是的,但是 Json.NET 没有与 ASP.NET Core 依赖注入(inject)集成。所以反序列化器不知道如何创建 ITestInterface 的实例。

do I need to set something else in the JSON options or use my own contract resolver.

是的,您应该付出一些努力来涵盖这种情况,而自定义契约(Contract)解析器似乎是最合适的方法。您应该采取的步骤如下:

  1. 定义自定义契约(Contract)解析器。您可以将其基于 Json.NET 使用的 DefaultContractResolver。您应该将 IServiceProvider 的实例传递给此解析器,它将用于注册类型的实例化。

  2. Startup.ConfigureServices() 中注册 Json.NET 反序列化过程中契约(Contract)解析器可以使用的所有类型。

  3. 创建自定义契约(Contract)解析器的实例并将其设置为 SerializerSettings.ContractResolver。在 Startup.ConfigureServices() 中,您还没有访问 IServiceProvider 的权限,因为它尚未创建(因为服务仍在注册中)。但是,您可以通过调用 services.BuildServiceProvider() 自行创建它。但请确保您已在此次通话前注册了所有必需的服务。

这是执行所有描述步骤的示例:

DependencyInjectionContractResolver 类:

public class DependencyInjectionContractResolver : DefaultContractResolver
{
private readonly IServiceProvider serviceProvider;
private readonly List<Type> registeredTypes;

public DependencyInjectionContractResolver(IServiceProvider serviceProvider, IEnumerable<Type> registeredTypes)
{
this.serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));
this.registeredTypes = registeredTypes?.ToList() ?? throw new ArgumentNullException(nameof(registeredTypes));
}

protected override JsonContract CreateContract(Type objectType)
{
JsonContract contract = base.CreateContract(objectType);

if (registeredTypes.Contains(objectType))
{
contract.DefaultCreator = () => serviceProvider.GetService(objectType);
}

return contract;
}
}

Startup.ConfigureServices(IServiceCollection 服务)方法:

public void ConfigureServices(IServiceCollection services)
{
services.AddTransient<ITestInterface, TestClass>();
// Register all other services here
// ...

services.AddMvc(options => options.RespectBrowserAcceptHeader = true)
.AddXmlDataContractSerializerFormatters()
.AddXmlSerializerFormatters()
.AddJsonOptions(o =>
{
o.SerializerSettings.ContractResolver = new DependencyInjectionContractResolver(services.BuildServiceProvider(),
new[] { typeof(ITestInterface) } );

o.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;
});
}

关于asp.net-core - 如何将依赖注入(inject)与 .NET Core 2 API 选项结合使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49362734/

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