I have a situation where I'm debating how to architect my controllers.
Consider the following controller:
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 );
...
}
In this controller, I use the command pattern and pass a model to my commandBus which interfaces with my domain. The first three [HttpPost]
methods on the controller are for handling jQuery ajax calls from a responsive file uploading UI.
Consider the situation where a user fills out a form (an interview) and uploads some files along with it. Although the user can upload the files before submitting the form, I don't want the uploaded files to be committed until AFTER they submit the form and it passes validation. That is why the last method on the controller is not an http endpoint. As such I have the following controller:
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);
}
}
The problem is I'm using IoC to inject a commandBus
into the FileSharingController so I cannot just instantiate it with default constructor as I am doing.
My options to consider:
- Create a custom controller factory to allow instantiating my controller anywhere in the code.
- Turn my FileSharingController in a WebAPI controller and treat as a service
Which is the better design path for this situation? If the latter case, how can I keep the CommitFileUploads()
method private? I don't want it to be exposed as an endpoint that can be triggered without first validating the rest of the form.