Buona pratica per l'istanziazione di oggetti in MVC

4

In MVC i modelli di dominio (dal livello del modello) dovrebbero istanziare altri modelli di dominio o tutti i modelli di dominio dovrebbero essere istanziati nei controllori e trasmessi usando le iniezioni di dipendenza?

Come lo implementate nelle applicazioni reali? Se scegli questo percorso non è il controller a ingrassare?

    
posta danidacar 13.08.2013 - 21:35
fonte

3 risposte

3

Nel contesto .NET, MVC è un framework per la creazione di siti Web.

  • M (Modello) si riferisce a un viewmodel , ovvero una struttura di dati che verrà utilizzata specificatamente per la visualizzazione. Esempi di modelli di visualizzazione:

    • DisplayCustomerViewModel - struttura dati che ha tutto il necessario per la visualizzazione delle informazioni sui clienti

    • DeleteCustomerViewModel - struttura dati che ha tutto il necessario per la rimozione del cliente (probabilmente id e nome del cliente a scopo di conferma).

  • Visualizza i modelli sono diversi dal tuo modello di dominio. Se non lo capisci, leggi di nuovo e fai qualche ricerca.

  • Non dovresti usare i tuoi modelli di dominio invece dei modelli di vista, punto.

  • Se vedi modello e modello di dominio sono gli stessi (per ora comunque), copia i dati dal modello di dominio nel modello di visualizzazione (usa il framework di mappatura automatica per risparmiare tempo).

V (isual) si riferisce a una pagina che dovrebbe avere una dipendenza dal tuo modello vista (M). Il suo unico scopo è quello di visualizzare i dati memorizzati in quel modello di vista.

C (ontroller) nei miei occhi dovrebbe:

  • Chiama un livello aziendale per ottenere dati o aggiornare i dati. Vedi l'esempio di seguito.

  • Il livello aziendale dovrebbe quindi restituire un risultato dell'operazione.

  • Il controllore prende il risultato e lo associa al modello di vista.

  • Il controllore decide se visualizzare semplicemente il modello di visualizzazione, reindirizzare l'utente o fare qualcos'altro.

  • In nessun momento il controller dovrebbe fare alcuna logica di business.

  • Idealmente, non dovresti fare riferimento al livello del dominio nel tuo progetto MVC (livello di presentazione). In questo modo non confonderai i modelli di dominio con i modelli di visualizzazione.

Esempio di ciò che considero una buona azione del controller:

public ActionResult UpdateCustomer(UpdateCustomerViewModel updateCustomerViewModel)
{
   if (!ModelState.IsValid)
      return View(updateCustomerViewModel);

   // I create a DTO that holds customer information necessary to do the update. I copy values from my view model to my DTO object.
   var updateCustomerDTO = AutoMapper.Map<UpdateCustomerDTO>(updateCustomerViewModel);

   // I have a command that encapsulates customer update logic. This command 
   // is in a business layer and it knows nothing about view models.
   // Dependency is a static class that exposes IoC container. 
   // normally I would set my commands through constructor though.
   var updateCustomerCommand = Dependency.Resolve<IUpdateCustomerCommand>();

   // When command executes, it produces a result. Result may be as simple as 
   // true (success) and false (failure). I however chose to have a custom
   // type representing a result of the command.
   var result = updateCustomerCommand.Execute(updateCustomerDTO);

   // Self explanatory
   if (result is SuccessfulCustomerUpdate)
      return Success();

   return Failure();
}

Solo per ricapitolare il flusso:

  • Il modello di vista è mappato a DTO
  • DTO viene passato al livello aziendale
  • Il livello aziendale estrae i dati dal DTO e alcuni funzionano parlando con il livello del dominio (Modelli di dominio)
  • Il livello aziendale rimanda il DTO o qualche tipo di oggetto risultato
  • Il livello di presentazione estrae i dati da DTO o dall'oggetto risultato e li associa al modello di vista
  • Il livello di presentazione mostra il modello di vista
risposta data 31.08.2013 - 09:59
fonte
1

Da quello che posso cogliere delle tue domande, dovresti esaminare l'uso di un livello di servizio applicativo tra il tuo controller e il tuo modello di dominio. Il controller utilizzerà Iniezione di dipendenza per il servizio dell'applicazione.

Il servizio orchestrerebbe quindi il tuo dominio e non contenesse alcuna logica di business. Il livello di servizio funge da confine tra il controller e il modello di dominio. L'aspetto dell'orchestrazione include il modo in cui i tuoi modelli di dominio vengono istanziati.

- MVC / UI layer

public UserController: Controller
{
    private readonly IUserService _userService;
    public UserController(IUserService userService)
    {
         _userService = userService;
    }

    public void SomeUserAction()
    {
        _userService.SomeUserAction();
    }

}

- Service Layer

public UserService : IUserService
{
    public void SomeUserAction()
    {
         //Orchestrate domain logic
    }
}

In questo modo impedisce al controller di ingrassare. Il controller conserva solo i riferimenti a ciascun servizio applicativo richiesto.

Martin Fowler ha un bell'articolo sul Service Layer

    
risposta data 15.08.2013 - 15:34
fonte
0

Nei modelli MVC standard non dovrebbero sapere nulla sugli altri livelli, inclusi altri modelli. È compito di Controller istanziarli.

Sfortunatamente, il link a "Service Layer" fornito nell'altra risposta porta solo a un contorno molto impreciso, indirizzando il lettore verso il libro per maggiori dettagli. In effetti, non sono riuscito a trovare una buona informazione dettagliata, quindi forse il concetto non è così diffuso? Ma da quello che vedo, sembra proprio un altro tipo di Controller, forse di gerarchia superiore, che orchestra altri Controller.

È possibile scrivere un controller dedicato per creare un'istanza di tutti i modelli, oppure diventa troppo grande, aggiungere singoli controller per determinati modelli.

    
risposta data 31.08.2013 - 05:42
fonte

Leggi altre domande sui tag