2013-02-08 8 views
6

コントローラの設計方法について議論している状況があります。 Iは、コマンドパターンを使用して、自分のドメインとのインタフェース私commandBusにモデルを渡し、このコントローラで別のコントローラのアクションを呼び出す - ファイルアップローダ - MVC 4の設計上の考慮

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); 
      ... 
     } 

は、次のコントローラを考えます。コントローラー上の最初の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); 
     } 

    } 

問題は、私は私がやっているように、私はちょうどデフォルトコンストラクタでそれをインスタンス化することはできませんFileSharingControllerにcommandBusを注入するのIoCを使用しています:そのように私には、以下のコントローラを持っています。考慮すべき

マイオプション:

  • どこかのコードで私のコントローラをインスタンス化できるようにするカスタムコントローラファクトリを作成します。
  • WebAPIのコントローラで私FileSharingControllerの電源を入れて、このような状況のためのより良い設計・パスでサービス

として扱う

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

  • 答えて

    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) 
        { 
         //.... 
        } 
    } 
    

    、その後、あなたはそれを呼び出す:あなたはDependencyResolverを使用しない場合、あなたは両方のコントローラのコンストラクタにICommandBusを渡し、

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

    か、およびそれを使用ヘルパークラスをインスタンス化するための参照。

    0

    単に別のコローラのオブジェクトを作成し、すべてのパブリックメソッドを使用するだけです。

    関連する問題