c# - 将现有控制器操作转换为通用方法
问题描述
在我的 ASP.NET 5 Web API 项目中,我发现我的许多核心控制器都包含完全相同的 CRUD 方法。我发现我只是复制/粘贴代码并搜索和替换主要类型。警钟!这引发了这样的想法:如果可能,我想创建这些操作的通用实现以减少类似代码。这将有助于代码的可维护性等。
关于我如何做到这一点的任何建议?这是 VehicleType 使用的一个示例类。我的其他类(组织、国家等)非常相似,并且都包含执行以下操作的方法:GetAll、Get、Create、Update 和 Delete。
[Authorize]
[ApiController]
[Route("api/[controller]")]
public class VehicleTypeController : Controller
{
private readonly IUnitOfWork _unitOfWork;
private readonly ILogger<VehicleTypeController> _logger;
private readonly IMapper _mapper;
public VehicleTypeController(IUnitOfWork unitOfWork, ILogger<VehicleTypeController> logger, IMapper mapper)
{
_unitOfWork = unitOfWork;
_logger = logger;
_mapper = mapper;
}
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> Get()
{
var countries = await _unitOfWork.VehicleTypes.GetAll();
var results = _mapper.Map<IList<VehicleTypeDTO>>(countries);
return Ok(results);
}
[HttpGet("{id:int}", Name = "Get")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> Get(int id)
{
var VehicleType = await _unitOfWork.VehicleTypes.Get(i => i.Id == id);
var results = _mapper.Map<VehicleTypeDTO>(VehicleType);
return Ok(results);
}
[Authorize(Roles = "Administrator")]
[HttpPost]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> Create([FromBody] CreateVehicleTypeDTO VehicleTypeDto)
{
if (!ModelState.IsValid)
{
_logger.LogError($"Invalid POST attempt in {nameof(CreateVehicleType)}");
return BadRequest(ModelState);
}
var VehicleType = _mapper.Map<VehicleType>(VehicleTypeDto);
await _unitOfWork.VehicleTypes.Insert(VehicleType);
await _unitOfWork.Save();
return CreatedAtRoute("Get", new { id = VehicleType.Id }, VehicleType);
}
[Authorize(Roles = "Administrator")]
[HttpPut("{id:int}")]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> Update(int id, [FromBody] UpdateVehicleTypeDTO VehicleTypeDto)
{
if (!ModelState.IsValid || id < 1)
{
_logger.LogError($"Invalid UPDATE attempt in {nameof(Update)}");
return BadRequest(ModelState);
}
var VehicleType = await _unitOfWork.VehicleTypes.Get(a => a.Id == id);
if (VehicleType == null)
{
_logger.LogError($"Submitted data is invalid.");
return BadRequest(ModelState);
}
_mapper.Map(VehicleTypeDto, VehicleType);
_unitOfWork.VehicleTypes.Update(VehicleType);
await _unitOfWork.Save();
return NoContent();
}
[Authorize(Roles = "Administrator")]
[HttpDelete("{id:int}")]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<IActionResult> Delete(int id)
{
if (id < 1)
{
_logger.LogError($"Invalid DELETE attempt in {nameof(Delete)}");
return BadRequest();
}
var VehicleType = _unitOfWork.VehicleTypes.Get(i => i.Id == id);
if (VehicleType == null)
{
_logger.LogError($"Invalid DELETE attempt in {nameof(Delete)}");
return BadRequest("Submitted data is invalid.");
}
await _unitOfWork.VehicleTypes.Delete(id);
await _unitOfWork.Save();
return NoContent();
}
}
用这些方法创建接口然后让这些类实现这个接口的最佳方法是什么?例如这样的事情......
public interface IGenericCRUD
{
Task<IActionResult> Get();
Task<IActionResult> Get(int id);
Task<IActionResult> Create([FromBody] object myDto);
Task<IActionResult> Update(int id, [FromBody] object myDto);
Task<IActionResult> Delete(int id);
}
然后使用反射来动态调用基于泛型类型的适当方法?
因此,创建一个实现 IGenericCRUD 并包含核心 CRUD 代码的通用 CRUD 类,但使用通用 T。类似...
public class GenericCrud<T, TEntityDto>
那么,在Get方法中,例如,是这样的吗?(它没有编译,所以我不确定我是否接近。)
public async Task<IList<TEntityDto>> Get()
{
var getAllResults = await _unitOfWork.GetType(T).GetAll();
var results = _mapper.Map<IList<TEntityDto>>(getAllResults);
return results;
}
我在正确的轨道上吗?有什么办法可以发布这个类的“通用”版本让我看到你的方法?
谢谢!
解决方案
推荐阅读
- ios - didReceiveRemoteNotification 函数调用了两次
- php - 如何使用证书发送 SOAP 数字签名消息
- qt - Qt BLE QLowEnergyDescriptor characteristicChanged(桌面操作系统)
- sql - 如何使用 ROLLUP 将总计移动到结果集的底部?
- python-3.x - 无法弄清楚Chatterbot的这个问题
- git - 如何将远程分支的提交写入我的本地分支?
- flutter - Flutter - 如何访问 Wifi 详细信息?
- c# - 为什么玩家从不改变步行速度从不改变动画/秒?
- documentum - Documentum - [DFC_BOF_CLASS_CACHE_INIT_ERROR] 无法初始化类缓存
- c - 是否可以“放松” VS Code 中的问题?