2013-02-08 16 views
6

Mam sytuację, w której debatuje się, jak zaprojektować swoje kontrolery.Wywoływanie akcji innego kontrolera - Uwzględnienie projektu dla programu do przesyłania plików - MVC 4

Rozważmy następujący Kontroler:

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

W tym kontrolerze, używam wzorzec polecenia i przekazać model do mojego commandBus która graniczy z mojej domeny. Pierwsze trzy metody [HttpPost] na kontrolerze są przeznaczone do obsługi wywołań jQuery ajax z responsywnego interfejsu do przesyłania plików.

Rozważ sytuację, w której użytkownik wypełni formularz (wywiad) i załaduje kilka plików wraz z nim. Mimo że użytkownik może przesłać pliki przed wysłaniem formularza, nie chcę, aby przesłane pliki zostały zatwierdzone do czasu, gdy po przesłaniu formularza przejdą sprawdzanie poprawności. Dlatego ostatnia metoda na kontrolerze nie jest punktem końcowym http. Jako takie mam następujący Kontroler:

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

    } 

Problem polega Używam IoC wstrzyknąć commandBus do FileSharingController więc nie mogę po prostu oznacz ją z domyślnego konstruktora jak robię.

Moje opcje do rozważenia:

  • utworzyć fabrykę zwyczaj kontrolera w celu umożliwienia instancji mój kontroler nigdzie w kodzie.
  • Włącz mój FileSharingController w kontrolerze WebAPI i traktować jako usługę

która jest lepsza droga konstrukcja dla tej sytuacji? Jeśli w tym ostatnim przypadku, jak mogę zachować prywatność metody CommitFileUploads()? Nie chcę, aby był wyświetlany jako punkt końcowy, który może zostać wywołany bez wcześniejszej weryfikacji pozostałej części formularza.

Odpowiedz

2

Można instancji kontrolera tak: metoda

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

Generic getService() to metoda rozszerzenie, więc upewnij się, że "za pomocą System.Web.Mvc;" wiersz w pliku cs.

Ale lepiej jest mieć klasę helpera, która jest odpowiedzialna za przechowywanie/przechowywanie już przesłanych plików i wywoływać je z obu kontrolerów, zamiast tworzenia instancji kontrolerów ręcznie.

Na przykład:

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

a potem nazwać:

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

Lub, jeśli nie chcesz używać DependencyResolver, przechodzą ICommandBus do konstruktorów zarówno sterownika, jak i używać odwołanie do instancji klasy pomocniczej.

0

po prostu stwórz obiekt innego gracza i używaj wszystkich jego publicznych metod.

Powiązane problemy