我正在努力避免出现“胖控制器”的情况。
有许多控制器调用一个API的示例,但是如果您的控制器需要调用两个或多个API怎么办?
您如何简化这种情况?似乎应该有一种更清洁的方法:
private ServiceTwo serviceTwo = new ServiceTwo();
private MailService mailService = new MailService();
[HttpPost]
public async Task<ActionResult> Index(Customer formData)
{
if (!ModelState.IsValid)
{
return View();
}
var apiOneService = new ApiOneService(formData);
if (apiOneService.ExistingUserCheck())
{
ModelState.AddModelError("Email", "* Email address already exists.");
return View(formData);
}
var apiTwoResult = serviceTwo.CreateTrial(formData);
var emailResult = await mailService.SendMailAsync((formData));
return RedirectToAction("Index", "TrialConfirmation");
}
答案 0 :(得分:1)
对于这么小的东西,您可以将逻辑提取到控制器中的其他方法:
[HttpPost]
public async Task<ActionResult> Index(Customer formData) {
if (!ModelState.IsValid) {
return View();
}
var ok = await CreateTrial(formData);
return ok
? (ActionResult)RedirectToAction("Index", "TrialConfirmation")
: View(formData);
}
}
protected async Task<bool> CreateTrial(Customer formData) {
var apiOneService = new ApiOneService(formData);
if (apiOneService.ExistingUserCheck()) return false;
var emailTask = mailService.SendMailAsync((formData));
var apiTwoResult = serviceTwo.CreateTrial(formData);
await emailTask;
return true;
}
对于更复杂的方法,您也可以将逻辑提取到单独的类或层中。
答案 1 :(得分:0)
您可以简化控制器,直到:
在这里您只能看到元数据定义:什么是id,哪些字段需要加载数据(一对多,许多需要加载,依此类推)。
实际上,您是在问如何编写内部DSL,以“更大的砖块”定义我的控制器。只要写
可能但不能带来完全的满足。人们坚持使用通用代码,因为它是通用的。即使冗长。
答案 2 :(得分:-1)
在某些类似情况下,我倾向于实现服务层,并通过依赖注入公开接口。 逻辑在服务层中,控制器只是将此逻辑公开给视图。