如何在不引用MVC包的扩展方法中注册JsonConverter供WebApi使用?
问题场景与解决方案
核心问题
在DDD分层项目中,自定义JsonConverter位于无法引用MVC包的项目中,如何通过扩展方法注册该转换器,使其在WebApi的响应序列化中生效,同时避免在Web项目的AddControllers中直接硬编码配置?
可行方案
方案一:拆分配置逻辑,隔离MVC依赖
这种方式既保持转换器所在项目的无MVC依赖特性,又能让Web项目轻松集成配置:
在转换器所在项目(无MVC引用):
定义仅依赖System.Text.Json的静态方法,负责添加自定义转换器:using System.Text.Json; using System.Text.Json.Serialization; public static class JsonConverterSetup { // 仅负责添加转换器,不涉及任何MVC类型 public static JsonSerializerOptions AddAliasConverters(this JsonSerializerOptions options) { options.Converters.Add(new AliasConverter()); return options; } } // 自定义转换器实现(仅依赖System.Text.Json) public class AliasConverter : JsonConverter<IAlias> { public override IAlias Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { using var doc = JsonDocument.ParseValue(ref reader); var kind = doc.RootElement.GetProperty("Kind").GetString(); return kind switch { nameof(AliasKind.Foo) => JsonSerializer.Deserialize<FooAlias>(doc.RootElement.GetRawText(), options), nameof(AliasKind.Relationship) => JsonSerializer.Deserialize<BarAlias>(doc.RootElement.GetRawText(), options), _ => throw new JsonException($"未知AliasKind类型: {kind}") }; } public override void Write(Utf8JsonWriter writer, IAlias value, JsonSerializerOptions options) { // 序列化时按对象实际类型输出 JsonSerializer.Serialize(writer, value, value.GetType(), options); } }在Web项目(可引用MVC和转换器项目):
在AddControllers的配置中调用上述静态方法,同时保持原有扩展方法的职责(仅注册服务):// Program.cs builder.Services.AddApplicationLayer(); // 仅注册领域/应用层服务,不涉及MVC配置 builder.Services.AddControllers() .AddJsonOptions(opt => { // 调用转换器项目中的配置方法,注入自定义转换器 opt.JsonSerializerOptions.AddAliasConverters(); });
方案二:利用DI配置选项实现自动注册
如果希望完全通过扩展方法自动完成配置,无需在Web项目中显式编写AddJsonOptions逻辑,可以借助IConfigureOptions接口:
在可引用MVC的项目(如Web项目或基础设施层):
实现配置JsonOptions的逻辑:using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; using System.Text.Json; public class JsonOptionsConfigurator : IConfigureOptions<JsonOptions> { public void Configure(JsonOptions options) { // 调用转换器项目中的配置方法 options.JsonSerializerOptions.AddAliasConverters(); } }在扩展方法中注册配置类:
在可引用MVC的项目中定义扩展方法,注册上述配置类:public static class DependencyInjection { public static IServiceCollection AddJsonConverterSetup(this IServiceCollection services) { services.ConfigureOptions<JsonOptionsConfigurator>(); return services; } }在Program.cs中调用扩展方法:
builder.Services.AddApplicationLayer(); builder.Services.AddJsonConverterSetup(); // 自动配置Json转换器 builder.Services.AddControllers();
关键说明
- 转换器本身仅依赖
System.Text.Json,可以安全放在无MVC引用的项目中; - 配置
JsonOptions的逻辑必须放在能引用MVC包的项目中(因为JsonOptions属于ASP.NET Core MVC的专用类型); - 两种方案都遵循了DDD的分层依赖原则,避免了跨层引用的问题。
内容的提问来源于stack exchange,提问作者boop
相关产品推荐
相关产品推荐

