泛型序列化Job DTO设计模式最佳实践及跨服务类型识别咨询
Job任务跨服务传递与泛型类型识别最佳实践
一、核心设计优化目标
解决两个核心问题:
- 跨服务反序列化时自动识别Job对应的泛型参数类型
- 消除switch分支硬编码,避免多场景重复维护Job类型映射逻辑
二、全局唯一Job类型映射配置
首先维护全局唯一的JobType与对应参数类型的映射关系,全程只需要维护这一份配置:
public static class JobTypeMapper { private static readonly IReadOnlyDictionary<JobType, Type> _dataTypeMap = new Dictionary<JobType, Type> { { JobType.Job1, typeof(Job1Data) }, { JobType.Job2, typeof(Job2Data) }, { JobType.Job3, typeof(Job3Data) } }; public static Type GetDataType(JobType jobType) => _dataTypeMap[jobType]; // 可选:扩展反射自动注册逻辑,新增Job类型无需手动改配置 // public static void ScanAndRegister() { /* 扫描所有标记了JobTypeAttribute的参数类自动注册 */ } }
同时给BaseJob补充JobType字段,无需访问泛型接口即可快速识别任务类型:
public class BaseJob { public string Id { get; set; } public JobType JobType { get; set; } }
三、跨服务反序列化泛型还原实现
反序列化时先读取JobType字段,再动态构造对应泛型类型完成反序列化,全程类型安全无需dynamic:
using Newtonsoft.Json.Linq; public static class JobDeserializer { public static BaseJob Deserialize(string jobJson) { // 先浅解析获取任务类型,避免全量反序列化后再转换 var jobJObj = JObject.Parse(jobJson); var jobType = jobJObj[nameof(BaseJob.JobType)].ToObject<JobType>(); // 从映射表获取对应的参数类型 var dataType = JobTypeMapper.GetDataType(jobType); // 构造具体的泛型Job<T>类型 var genericJobType = typeof(Job<>).MakeGenericType(dataType); // 反序列化为强类型的泛型实例 return (BaseJob)jobJObj.ToObject(genericJobType); } }
四、类型安全的Job处理逻辑(消除switch分支)
采用处理器模式实现Job的分发处理,新增Job类型仅需新增对应处理器,无需修改原有分发逻辑:
1. 定义处理器公共接口
public interface IJobHandler { JobType SupportedJobType { get; } void Handle(BaseJob job); }
2. 每个Job类型对应独立的处理器实现
// Job1对应的处理器 public class Job1Handler : IJobHandler { public JobType SupportedJobType => JobType.Job1; public void Handle(BaseJob job) { // 直接转换为强类型泛型Job,无需dynamic var typedJob = (Job<Job1Data>)job; Job1Data data = typedJob.Object; // 直接使用强类型参数执行业务逻辑 } } // Job2、Job3处理器以此类推
3. 实现自动注册的处理器工厂
通过反射自动扫描所有处理器实现,新增处理器无需手动注册:
public static class JobHandlerFactory { private static readonly IReadOnlyDictionary<JobType, IJobHandler> _handlerMap; static JobHandlerFactory() { // 扫描当前域所有程序集的IJobHandler实现 var handlers = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(asm => asm.GetTypes()) .Where(type => typeof(IJobHandler).IsAssignableFrom(type) && !type.IsAbstract) .Select(Activator.CreateInstance) .Cast<IJobHandler>(); _handlerMap = handlers.ToDictionary(h => h.SupportedJobType); } public static IJobHandler GetHandler(JobType jobType) => _handlerMap[jobType]; }
4. 最终Job处理入口
不需要任何switch分支,一行代码完成分发:
public void ProcessJob(BaseJob job) { var handler = JobHandlerFactory.GetHandler(job.JobType); handler.Handle(job); }
五、原有Job类的性能优化
给泛型Job类加反序列化缓存,避免每次读取Object属性都重复反序列化:
public class Job<T>: BaseJob, IJob<T> { private T _objectCache; public JobType Job { get; set; } public string DataObject { get; set; } [JsonIgnore] public T Object { get { if (_objectCache == null && !string.IsNullOrEmpty(DataObject)) { _objectCache = JsonConvert.DeserializeObject<T>(DataObject); } return _objectCache; } } public void SetJobInfo(T data) { DataObject = JsonConvert.SerializeObject(data); _objectCache = data; } }
内容的提问来源于stack exchange,提问作者KeithMac
相关产品推荐
相关产品推荐

