2013-02-08 25 views
6

Tôi có một tình huống mà tôi đang tranh luận về cách kiến ​​trúc các bộ điều khiển của mình.Gọi hành động của bộ điều khiển khác - Thiết kế xem xét cho Trình tải lên tệp - MVC 4

Hãy xem xét các điều khiển sau:

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

Trong điều khiển này, tôi sử dụng mô hình chỉ huy và thông qua một mô hình để commandBus tôi mà giao diện với tên miền của tôi. Ba phương thức đầu tiên là [HttpPost] trên bộ điều khiển để xử lý các cuộc gọi jQuery ajax từ giao diện người dùng tải lên tệp đáp ứng.

Hãy xem xét các tình huống mà một người sử dụng điền vào một mẫu (một cuộc phỏng vấn) và tải lên một số tác phẩm cùng với nó. Mặc dù người dùng có thể tải lên các tệp trước khi gửi biểu mẫu, tôi không muốn các tệp được tải lên được cam kết cho đến SAU KHI họ gửi biểu mẫu và vượt qua xác thực. Đó là lý do tại sao phương pháp cuối cùng trên bộ điều khiển không phải là một điểm cuối http. Như vậy tôi có bộ điều khiển sau:

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

    } 

Vấn đề là tôi đang sử dụng IoC để tiêm một commandBus vào FileSharingController vì vậy tôi không thể chỉ nhanh chóng nó với constructor mặc định như tôi đang làm.

lựa chọn của tôi để xem xét:

  • Tạo một nhà máy điều khiển tùy chỉnh để cho phép instantiating điều khiển của tôi bất cứ nơi nào trong các mã.
  • Rẽ FileSharingController của tôi trong một bộ điều khiển WebAPI và đối xử như một dịch vụ

Đó là con đường thiết kế tốt hơn cho tình huống này? Nếu trường hợp sau, làm thế nào tôi có thể giữ riêng phương thức CommitFileUploads()? Tôi không muốn nó được tiếp xúc như một điểm cuối có thể được kích hoạt mà không cần xác nhận phần còn lại của biểu mẫu.

Trả lời

2

Bạn có thể nhanh chóng điều khiển của bạn như thế này:

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

Generic GetService() phương pháp là phương pháp mở rộng, do đó hãy chắc chắn rằng bạn đã "using System.Web.Mvc;" dòng trong tệp cs.

Nhưng sau đó, nó tốt hơn để có lớp helper đó là trách nhiệm giữ/lưu trữ các file đã được tải lên, và gọi nó là từ cả hai bộ điều khiển, thay vì instantiating điều khiển bằng tay.

Ví dụ:

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

và sau đó bạn gọi nó là:

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

Hoặc, nếu bạn không muốn sử dụng DependencyResolver, bạn vượt qua ICommandBus đơn vị thi công của cả hai bộ điều khiển, và sử dụng rằng tham chiếu đến lớp trợ giúp khởi tạo.

0

chỉ cần tạo đối tượng của một conroller khác và sử dụng tất cả các phương thức công khai của nó.

Các vấn đề liên quan