我有一种情况,我正在讨论如何构建我的控制器。
考虑以下控制器:
public class FileSharingController : Controller
{
private readonly ICommandBus commandBus;
public FileSharingController(ICommandBus commandBus)
{
this.commandBus = commandBus;
}
[HttpPost]
public ActionResult PrepareMetadata(int blocksCount, string fileName, long fileSize)
{
...
}
[HttpPost]
public ActionResult ClearFileMetadata(string fileName){
...
}
[HttpPost] [ValidateInput(false)] //$.ajax({ data: html5FormDataFileChunk , processData: false ... })
public ActionResult UploadBlock(string fileName, int blockId){
var fileUploadCommand = (FileUploadCommand)ExtractFromSessionData(fileName);
var result = commandBus.Submit(fileUploadCommand);
...
}
public ActionResult CommitFileUploads(string[] filesToCommit){
var commitFileUploadCommand = (CommitFileUploadCommand)ExtractFromSessionData(fileName);
var result = commandBus.Submit(commitFileUploadCommand );
...
}
在这个控制器中,我使用命令模式并将模型传递给与我的域接口的 commandBus。控制器上的前三个[HttpPost]
方法用于处理来自响应式文件上传 UI 的 jQuery ajax 调用。
考虑用户填写表格(采访)并上传一些文件的情况。尽管用户可以在提交表单之前上传文件,但我不希望在提交表单并通过验证之前提交上传的文件。这就是为什么控制器上的最后一个方法不是 http 端点的原因。因此,我有以下控制器:
public class InterviewController : Controller
{
[HttpGet]
public ActionResult UserInterview()
{
InterviewViewModel viewModel = new InterviewViewModel ();
return PartialView(viewModel);
}
[HttpPost] [AllowAnonymous]
public ActionResult UserInterview(InterviewViewModel viewModel)
{
if(ModelState.IsValid)
{
var fileSharingController = new FileSharingController();
fileSharingController.CommitFileUploads(viewModel.Files);
}
return PartialView(viewModel);
}
}
问题是我正在使用 IoC 将 acommandBus
注入到 FileSharingController 中,所以我不能像我正在做的那样使用默认构造函数来实例化它。
我要考虑的选择:
- 创建一个自定义控制器工厂以允许在代码中的任何位置实例化我的控制器。
- 在 WebAPI 控制器中打开我的 FileSharingController 并将其视为服务
对于这种情况,哪种设计路径更好?如果是后一种情况,我怎样才能保持CommitFileUploads()
方法私有?我不希望它被暴露为可以在不首先验证表单的其余部分的情况下触发的端点。