6

我有一种情况,我正在讨论如何构建我的控制器。

考虑以下控制器:

    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()方法私有?我不希望它被暴露为可以在不首先验证表单的其余部分的情况下触发的端点。

4

2 回答 2

2

你可以像这样实例化你的控制器:

ICommandBus commandBus = DependencyResolver.Current.GetService<ICommandBus>();
var fileShareController = new FileSharingController(commandBus);

通用 GetService() 方法是扩展方法,因此请确保您有“使用 System.Web.Mvc;” cs 文件中的行。

但是,最好有一个帮助类来负责保存/存储已上传的文件,并从两个控制器调用它,而不是手动实例化控制器。

例如:

public class FileUploadManager
{
    public FileUploadManager(ICommandBus commandBus, HttpSessionStateBase sessionState)
    {
         //....
    }
}

然后你称之为:

ICommandBus commandBus = DependencyResolver.Current.GetService<ICommandBus>();
var fileShareController = new FileUploadManager(commandBus, this.HttpContext.Session);

或者,如果您不想使用 DependencyResolver,则将 ICommandBus 传递给两个控制器的构造函数,并使用该引用来实例化帮助程序类。

于 2013-02-14T18:56:12.640 回答
0

只需创建另一个控制器的对象并使用其所有公共方法。

于 2013-02-15T10:20:41.943 回答