如何在单个Controller中实现多类型商品的创建逻辑?
整合多类型商品创建的REST API Controller实现
针对你的场景,用工厂方法模式可以完美消除Controller中的重复代码,同时兼顾后续扩展需求,以下是具体实现步骤:
1. 定义统一的DTO标记接口
让所有商品创建DTO实现同一个标记接口,用于统一接收请求:
public interface ICreateProductDto { } // 原有DTO实现该接口 public class CreateProductDto : ICreateProductDto { // 你的原有字段:Name、Description等 } public class CreateDollBoxDto : ICreateProductDto { // 玩偶盒专属字段 } public class CreateChocoboxDto : ICreateProductDto { // 巧克力盒专属字段 }
2. 实现产品工厂类
将不同DTO的创建逻辑封装到工厂中,隔离Controller和具体业务:
public interface IProductFactory { Task<Product> CreateProductAsync(ICreateProductDto dto); } public class ProductFactory : IProductFactory { private readonly IProductService _productService; public ProductFactory(IProductService productService) { _productService = productService; } public async Task<Product> CreateProductAsync(ICreateProductDto dto) { return dto switch { CreateProductDto baseDto => await _productService.CreateProduct(baseDto), CreateDollBoxDto dollDto => await _productService.CreateDollbox(dollDto), CreateChocoboxDto chocoDto => await _productService.CreateChocobox(chocoDto), // 新增商品类型时,在此添加对应分支即可 _ => throw new ArgumentException("不支持的商品创建DTO类型", nameof(dto)) }; } }
3. 简化Controller代码
将多个创建方法合并为一个,依赖工厂处理具体逻辑:
[ApiController] [Route("api/products")] public class ProductsController : ControllerBase { private const string GetByIdRouteName = "GetProductById"; private readonly IProductFactory _productFactory; public ProductsController(IProductFactory productFactory) { _productFactory = productFactory; } [HttpPost] public async Task<ActionResult<Product>> CreateProduct([FromBody] ICreateProductDto dto) { try { var newProduct = await _productFactory.CreateProductAsync(dto); return CreatedAtRoute(GetByIdRouteName, new { id = newProduct.Id }, newProduct); } catch (ArgumentException ex) { return BadRequest(ex.Message); } } }
4. 注册工厂服务
在依赖注入容器中注册工厂类(以.NET 6+为例):
builder.Services.AddScoped<IProductFactory, ProductFactory>();
优势说明
- 彻底消除Controller中的重复代码,符合单一职责原则
- 新增商品类型时,仅需添加新DTO并扩展工厂分支,无需修改Controller
- 业务逻辑集中在工厂类,便于单元测试和维护
内容的提问来源于stack exchange,提问作者kErElLlLlL
相关产品推荐
相关产品推荐

