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 に渡します。コントローラーの最初の 3 つの[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 を使用commandBusして FileSharingController に a を挿入しているため、私が行っているようにデフォルトのコンストラクターでインスタンス化することはできません。

考慮すべき私のオプション:

  • カスタム コントローラー ファクトリを作成して、コード内の任意の場所でコントローラーをインスタンス化できるようにします。
  • FileSharingController を WebAPI コントローラーで有効にして、サービスとして扱います

この状況に適した設計パスはどれですか? 後者の場合、どうすればCommitFileUploads()メソッドをプライベートに保つことができますか? 最初にフォームの残りを検証せずにトリガーできるエンドポイントとして公開したくありません。

4

2 に答える 2

2

次のようにコントローラをインスタンス化できます。

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

一般的なGetService()メソッドは拡張メソッドであるため、「usingSystem.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 に答える