.NET 7 REST API多格式数据加载扩展:求低侵入性设计方案
专业实现方案建议
1. 定义统一抽象接口(可选搭配抽象基类)
先抽离数据读取的核心行为,优先用接口实现面向抽象编程,灵活性更强;如果不同格式有通用逻辑(比如文件路径校验),再抽象基类封装复用逻辑,具体格式的仓库类继承基类即可:
// 核心数据读取接口 public interface IDataRepository { Task<IEnumerable<YourDataModel>> LoadDataAsync(string filePath); } // 抽象基类封装通用逻辑 public abstract class BaseDataRepository : IDataRepository { protected void ValidateFilePath(string filePath) { if (string.IsNullOrWhiteSpace(filePath)) throw new ArgumentNullException(nameof(filePath)); if (!File.Exists(filePath)) throw new FileNotFoundException("数据文件不存在", filePath); } public abstract Task<IEnumerable<YourDataModel>> LoadDataAsync(string filePath); } // CSV格式实现(复用原有代码) public class CsvDataRepository : BaseDataRepository { public override async Task<IEnumerable<YourDataModel>> LoadDataAsync(string filePath) { ValidateFilePath(filePath); // 原有CSV读取逻辑直接迁移 ... } } // XML格式实现 public class XmlDataRepository : BaseDataRepository { public override async Task<IEnumerable<YourDataModel>> LoadDataAsync(string filePath) { ValidateFilePath(filePath); // XML读取逻辑 ... } } // JSON格式实现同理 public class JsonDataRepository : BaseDataRepository { ... }
2. 配置文件定义格式标识
在appsettings.json中添加配置项,明确当前使用的数据格式:
{ "DataSettings": { "DataSourceType": "Csv" // 可选值:Csv/Xml/Json } }
3. Startup阶段动态注入对应实现
在Program.cs(.NET 6+)或Startup.cs中读取配置,根据配置值注册对应的IDataRepository实现,确保运行时固定:
var dataSourceType = builder.Configuration["DataSettings:DataSourceType"]?.Trim().ToLowerInvariant(); switch (dataSourceType) { case "csv": builder.Services.AddScoped<IDataRepository, CsvDataRepository>(); break; case "xml": builder.Services.AddScoped<IDataRepository, XmlDataRepository>(); break; case "json": builder.Services.AddScoped<IDataRepository, JsonDataRepository>(); break; default: // 默认兼容原有CSV逻辑 builder.Services.AddScoped<IDataRepository, CsvDataRepository>(); break; }
4. 业务层直接依赖接口,无需改动原有逻辑
原有业务服务只需要注入IDataRepository,完全不用关心具体格式实现,原有业务逻辑零改动:
public class YourBusinessService { private readonly IDataRepository _dataRepository; public YourBusinessService(IDataRepository dataRepository) { _dataRepository = dataRepository; } public async Task ExecuteBusinessLogic(string filePath) { var data = await _dataRepository.LoadDataAsync(filePath); // 原有业务逻辑完全保留 ... } }
方案优势对比你的初步思路
- 开闭原则:新增格式仅需添加对应实现类,修改配置和Startup分支即可,原有代码完全不动
- 解耦彻底:业务层只依赖抽象接口,避免硬编码判断逻辑,后续迭代更顺畅
- 扩展性强:后续新增Excel、YAML等格式,只需添加对应仓库类,改动极小
- 配置驱动:通过配置文件灵活切换数据源格式,无需重新编译
额外优化建议
- 把
DataSourceType定义为枚举类,避免字符串硬编码错误:
public enum DataSourceType { Csv, Xml, Json }
配置绑定时直接用枚举,代码更严谨:
var dataSettings = builder.Configuration.GetSection("DataSettings").Get<DataSettings>(); switch (dataSettings.DataSourceType) { case DataSourceType.Csv: ... }
- 如果格式类型较多,可封装工厂类创建实例,简化Startup逻辑:
public static class DataRepositoryFactory { public static IDataRepository Create(DataSourceType type) { return type switch { DataSourceType.Csv => new CsvDataRepository(), DataSourceType.Xml => new XmlDataRepository(), DataSourceType.Json => new JsonDataRepository(), _ => new CsvDataRepository() }; } }
Startup中调用工厂注入:
var dataType = builder.Configuration.GetSection("DataSettings").Get<DataSettings>().DataSourceType; builder.Services.AddScoped<IDataRepository>(_ => DataRepositoryFactory.Create(dataType));
内容的提问来源于stack exchange,提问作者nathano
相关产品推荐
相关产品推荐

