C#中仅单一属性生效的对象架构设计方案咨询
方案结论
你要的单属性承载多类型认证信息的方案完全可行,核心通过多态序列化实现,相比原有多个可空属性搭配枚举判断的结构,能消除大量冗余null校验逻辑,后续扩展认证方式也更灵活。
具体实现(基于.NET默认的System.Text.Json序列化器)
首先对原有代码做两处小修正:补全原代码中缺失类型定义的JWT认证属性、给枚举中的Anonymous匿名访问补充对应实现类,再通过序列化特性配置多态映射规则:
// 认证信息抽象基类,所有认证方式均继承该类 [JsonPolymorphic(TypeDiscriminatorPropertyName = "authMethod")] [JsonDerivedType(typeof(AnonymousAuthentication), typeDiscriminator: (int)ServiceAuthenticationMethod.Anonymous)] [JsonDerivedType(typeof(BasicAuthentication), typeDiscriminator: (int)ServiceAuthenticationMethod.BasicAuthentication)] [JsonDerivedType(typeof(SigV4Authentication), typeDiscriminator: (int)ServiceAuthenticationMethod.SigV4)] [JsonDerivedType(typeof(JwtAuthentication), typeDiscriminator: (int)ServiceAuthenticationMethod.Jwt)] public abstract class AuthenticationBase { // 所有认证方式的公共逻辑/属性可定义在此处 } // 匿名访问实现,对应枚举中的Anonymous类型 public class AnonymousAuthentication : AuthenticationBase { } public class BasicAuthentication : AuthenticationBase { public string UserName { get; set; } public string Password { get; set; } } public class SigV4Authentication : AuthenticationBase { public string AccessKey { get; set; } public string SecretKey { get; set; } public string Region { get; set; } public string ServiceName { get; set; } public string SessionToken { get; set; } } public class JwtAuthentication : AuthenticationBase { public string Token { get; set; } } // 保留原有枚举,作为类型判别常量,也方便业务逻辑做类型判断 public enum ServiceAuthenticationMethod { Anonymous = 1, BasicAuthentication = 2, SigV4 = 3, Jwt = 4, }
重构后的APIAuth类仅保留你需要的单属性即可:
public class APIAuth { // 基类类型可承载所有派生认证类的实例 public AuthenticationBase AuthenticationType { get; set; } }
该实现的使用效果完全匹配你的需求:
- 存储序列化时,直接序列化
AuthenticationType属性即可,序列化器会自动写入类型判别字段authMethod(值为对应枚举的int值)和对应认证参数,不需要手动根据枚举选择属性序列化 - 读取反序列化时,直接将存储的JSON反序列化为
APIAuth类型即可,序列化器会自动根据authMethod字段将AuthenticationType转换为对应的具体认证类实例,不需要手动写分支判断 - 业务逻辑处理时,直接用C#模式匹配即可获取具体认证参数,不需要做冗余null校验:
if (apiAuth.AuthenticationType is BasicAuthentication basicAuth) { // 直接使用basicAuth.UserName、basicAuth.Password处理逻辑 }
其他架构优化建议
- 如果你项目用的是Newtonsoft.Json序列化器,实现逻辑完全一致,只需要将System.Text.Json的多态特性替换为Newtonsoft的JsonSubtypes多态转换器配置即可
- 原有结构属于典型的"标签类反模式":用枚举标签区分同一字段位置的不同类型数据,后续新增认证方式时必须修改APIAuth类、修改所有分支判断逻辑,很容易漏改引发bug。重构后的多态结构完全符合开闭原则:新增认证方式只需要新增继承基类的认证实现、加一行派生类型映射配置即可,不需要修改原有APIAuth定义和序列化逻辑
- 如果使用EF Core 7+做数据库持久化,直接将
AuthenticationType配置为映射到数据库JSON字段即可,ORM原生支持多态JSON类型的读写,不需要自定义值转换器 - 如果业务场景中需要频繁获取当前认证方式的枚举值,可以给基类增加抽象属性,让每个派生类返回对应枚举值,避免每次都做类型判断:
public abstract class AuthenticationBase { public abstract ServiceAuthenticationMethod AuthMethod { get; } } // 以Basic认证为例,其他派生类同理重写属性 public class BasicAuthentication : AuthenticationBase { public override ServiceAuthenticationMethod AuthMethod => ServiceAuthenticationMethod.BasicAuthentication; public string UserName { get; set; } public string Password { get; set; } }
内容的提问来源于stack exchange,提问作者Sunny
相关产品推荐
相关产品推荐

