14

Nella mia applicazione ASP.NET MVC, sto utilizzando unità di lavoro e modelli di repository per l'accesso ai dati.Dove convertire il modello di business per visualizzare il modello?

Utilizzando l'unità della classe di lavoro e il repository definito al suo interno, sto recuperando il set relativo di entità nel mio controller. Con la mia conoscenza da principiante, posso pensare a due modi per recuperare il modello di business e convertirlo in view model.

  • Repository restituisce il modello di business al controllore, questo modello di mappato per visualizzare modello, o
  • Repository si converte modello commerciale per visualizzare il modello e poi viene restituito al controllore.

Attualmente sto usando il primo approccio, ma il mio codice di controllo ha iniziato a sembrare brutto e a lungo per i modelli di visualizzazione con molte proprietà.

D'altra parte, penso, dal momento che il mio repository è chiamato UserRepository (per esempio), dovrebbe essere restituito il modello di business direttamente, invece di qualche modello che è utile solo per un'unica vista.

Quale di questi ritiene che sia una buona pratica per i grandi progetti? C'è un modo alternativo?

Grazie.

+1

La mia [risposta] [1] a questa domanda dovrebbe spiegare come ciò può essere fatto meglio. [1]: http://stackoverflow.com/questions/3747383/best-practices-to-partition-model-code-to-logical-parts-in-mvc-which-is-the- bes/3747474 # 3747474 –

risposta

20

repository dovrebbe tornare modelli di dominio, non visualizzare i modelli. Per quanto riguarda la mappatura tra i modelli e i modelli di vista, personalmente utilizzo AutoMapper quindi ho un livello di mappatura separato ma questo livello viene chiamato dal controller.

Ecco come un tipico GET azione del controller potrebbe essere simile:

public ActionResult Foo(int id) 
{ 
    // the controller queries the repository to retrieve a domain model 
    Bar domainModel = Repository.Get(id); 

    // The controller converts the domain model to a view model 
    // In this example I use AutoMapper, so the controller actually delegates 
    // this mapping to AutoMapper but if you don't have a separate mapping layer 
    // you could do the mapping here as well. 
    BarViewModel viewModel = Mapper.Map<Bar, BarViewModel>(domainModel); 

    // The controller passes a view model to the view 
    return View(viewModel); 
} 

che ovviamente potrebbe essere ridotto con un filtro un'azione personalizzata al fine di evitare la logica di mappatura ripetitiva:

[AutoMap(typeof(Bar), typeof(BarViewModel))] 
public ActionResult Foo(int id) 
{ 
    Bar domainModel = Repository.Get(id); 
    return View(domainModel); 
} 

L'AutoMap personalizzato il filtro azione sottoscrive l'evento OnActionExecuted, intercetta il modello passato al risultato della vista, richiama il livello di mappatura (AutoMapper nel mio caso) per convertirlo in un modello di vista e lo sostituisce per la vista. La vista è ovviamente fortemente tipizzata per il modello di vista.

+0

ty molto. Non sapevo di Automapper. È ciò di cui ho bisogno nel mio problema. –

+0

L'approccio del filtro azioni personalizzato è verificabile? Come funzionerebbe il mappatore automatico se questo fosse stato chiamato all'interno di un test unitario? –

+1

@JoshuaBarker, l'intero punto di un test unitario è che si sta testando una funzionalità in isolamento. Quindi cosa vuoi testare in isolamento qui? L'attributo AutoMap? Ottimo, vai avanti e scrivi un test unitario per questo. O l'azione del controllore che sta passando il modello di dominio alla vista? Ottimo, vai avanti e scrivi un test unitario per questo. O il fatto che l'azione del tuo controller sia decorata con l'attributo AutoMap? Ottimo, vai avanti e scrivi un test unitario per questo. Finora sono stati scritti 3 test unitari con tutto il necessario per verificare che l'azione del controller funzioni come previsto. –

2

Penso che il repository dovrebbe restituire il modello di business.

È quindi possibile utilizzare uno strumento come Automapper per mappare automaticamente le proprietà sul proprio modello di visualizzazione e liberarsi del codice di mappatura manuale. Questo approccio è molto utile se non si desidera esporre tutte le proprietà delle entità aziendali o la struttura dei componenti alla vista.

È inoltre possibile trovare questo post utile, dove è possibile eliminare le chiamate di mappatura manuale (sorta di) e fornisce anche un buon esempio di come utilizzare viewmodels ecc (a mio parere) - o almeno qualche tipo di ispirazione.

Estratto dalla carica (l'attributo fa il modello di modulo busioness conversione al ViewModel):

[AutoMap(typeof(Product), typeof(ShowProduct))] 
public ActionResult Details(int id) 
{ 
    var product = _productRepository.GetById(id); 

    return View(product); 
} 
+0

molto. La risposta di Darin è un po 'dettagliata, quindi accetto la sua risposta. Spero non ti dispiaccia. –

+0

Grazie, è bello. Grazie per le informazioni - Sono d'accordo sul fatto che la risposta di Darin abbia lo stesso contenuto ma la presenta meglio (e quindi è la risposta migliore). Ti suggerisco comunque di leggere il link, perché potrebbero esserci altre informazioni interessanti su Viewmodels ecc. –

+0

grazie. Lo sto leggendo al momento :) –

Problemi correlati