单控制器处理多模型API调用的泛型优化方案咨询
解决方案
1. 统一泛型接口定义
替换30个独立接口,定义通用泛型数据访问接口,所有实体的DAL类都实现该接口:
public interface IGenericDal<T> where T : class { IEnumerable<T> GetAll(); } // State实体的DAL实现示例 public class StateDal : IGenericDal<State> { public IEnumerable<State> GetAll() { // 此处编写State数据查询逻辑 return new List<State>(); } } // Country实体的DAL实现示例 public class CountryDal : IGenericDal<Country> { public IEnumerable<Country> GetAll() { // 此处编写Country数据查询逻辑 return new List<Country>(); } }
2. 注册泛型服务到DI容器
在Program.cs(或Startup.cs)中注册所有泛型DAL实现:
// 若所有实体的DAL逻辑通用,可直接注册通用泛型实现 builder.Services.AddScoped(typeof(IGenericDal<>), typeof(GenericDal<>)); // 若部分实体有自定义DAL逻辑,单独注册以覆盖通用实现 builder.Services.AddScoped<IGenericDal<State>, StateDal>(); builder.Services.AddScoped<IGenericDal<Country>, CountryDal>(); // 依次完成剩余28个实体的DAL注册
3. 控制器中通过类型映射+服务定位处理请求
保留单个控制器,注入IServiceProvider并维护section与实体类型的映射字典,根据请求参数动态获取对应DAL实例:
[ApiController] [Route("api/[controller]")] public class DataController : ControllerBase { private readonly IServiceProvider _serviceProvider; private readonly Dictionary<string, Type> _sectionTypeMap = new() { { "state", typeof(State) }, { "country", typeof(Country) }, { "city", typeof(City) }, // 补充剩余27个section与实体类型的映射关系 }; public DataController(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; } [HttpGet("{section}")] public ActionResult GetModelBySection(string section) { if (!_sectionTypeMap.TryGetValue(section.ToLower(), out var entityType)) { return NotFound("Section not found"); } // 构造泛型接口类型 var genericDalType = typeof(IGenericDal<>).MakeGenericType(entityType); // 从DI容器获取对应DAL实例 var dalInstance = _serviceProvider.GetService(genericDalType); if (dalInstance == null) { return StatusCode(StatusCodes.Status500InternalServerError, "Service not registered"); } // 调用GetAll方法并返回结果 var getAllMethod = genericDalType.GetMethod(nameof(IGenericDal<object>.GetAll)); var result = getAllMethod?.Invoke(dalInstance, null); return Ok(result); } }
4. 可选优化:封装工厂类解耦
若不想在控制器中直接使用IServiceProvider,可封装工厂类简化逻辑:
public class DalFactory { private readonly IServiceProvider _serviceProvider; private readonly Dictionary<string, Type> _sectionTypeMap; public DalFactory(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; _sectionTypeMap = new Dictionary<string, Type> { { "state", typeof(State) }, { "country", typeof(Country) }, // 补充其他映射关系 }; } public object GetDal(string section) { if (!_sectionTypeMap.TryGetValue(section.ToLower(), out var entityType)) { return null; } var genericDalType = typeof(IGenericDal<>).MakeGenericType(entityType); return _serviceProvider.GetService(genericDalType); } }
控制器中注入DalFactory后简化方法:
private readonly DalFactory _dalFactory; public DataController(DalFactory dalFactory) { _dalFactory = dalFactory; } [HttpGet("{section}")] public ActionResult GetModelBySection(string section) { var dalInstance = _dalFactory.GetDal(section); if (dalInstance == null) { return NotFound("Section not found"); } var getAllMethod = dalInstance.GetType().GetMethod(nameof(IGenericDal<object>.GetAll)); var result = getAllMethod?.Invoke(dalInstance, null); return Ok(result); }
内容的提问来源于stack exchange,提问作者IMRUP
相关产品推荐
相关产品推荐

