2013-02-15 8 views
58

Da quanto ho capito, MVC separa le definizioni di classe (modello) dalla presentazione (vista) tramite la "colla" che è il controller. Il responsabile del trattamento dovrebbe avere un'unica responsabilità e quindi essere verificabile. ViewModels viene utilizzato per riunire i dati di più entità e per "massaggiare" i dati dal controller per la vista.Creazione di un livello di servizio per la mia applicazione MVC?

Sembra che la logica aziendale non abbia davvero un luogo ... quindi sto pensando che un altro livello per i servizi sarebbe adatto. Non sono sicuro di dove posizionare questo livello, o come costruire i servizi - dovrebbe essere una classe chiamata "servizi" che contiene un sacco di funzioni? Sono un po 'nuovo in MVC, quindi qualsiasi tipo di materiale di lettura, di campioni o di consigli per principianti in generale sarebbe fantastico.

risposta

97

Di solito utilizzo un livello di servizio durante lo sviluppo dell'applicazione ASP.NET MVC. È simile allo Service Layer Pattern che Martin Fowler discute in Patterns of Enterprise Application Architecture. Incapsula la tua logica di business e rende i controller abbastanza sottili. Fondamentalmente i controllori usano il livello di servizio per ottenere i modelli di dominio che vengono poi trasformati in modelli di vista. Io uso anche lo Unit of Work Design Pattern per gestire le transazioni e lo Repository Design Pattern per incapsulare il livello di accesso ai dati per semplificare i test delle unità e per poter facilmente scambiare gli ORM. Questa figura mostra i tipici layer che utilizzo in un'applicazione MVC.

MVC Architecture

Il livello di servizio è etichettato come "Application o di livello di dominio" in questo schema perché ho trovato persone si confondono quando si utilizza il termine "Service Layer". Tendono a pensare che questo sia un servizio web. In realtà è un assembly che può essere utilizzato dalla tecnologia del servizio Web preferita, come ASP.NET Web API o WCF, nonché un controller.

Come per le convenzioni di denominazione, di solito utilizzo qualcosa che descrive il dominio seguito dal servizio.Ad esempio, se ho un livello di servizio che gestisce l'appartenenza utente, avrei una classe denominata MembershipService che ha tutti i metodi necessari per i controller e i servizi Web per interrogare e manipolare il dominio di appartenenza. Nota che potresti avere diversi domini nella stessa applicazione in modo da poter avere più livelli di servizio. Il mio punto di essere qui che non devi avere un servizio monolitico che si prende cura di tutta l'applicazione.

+0

Grazie Kevin. >>> – user2062383

+4

Esiste un buon esempio là fuori che implementa questa metodologia? – Animesh

+0

@Animesh devi solo comporre esempi nella rete, codice EF + prima o modello POCO per DAL, T4Scaffolding per generare repository e UnitOfWork, il servizio è solo un coordinamento tra DAL e POCO che incapsulano la logica di business. Quindi ASP.NET MVC Controller O WebApi che chiama solo il livello di servizio e mostra i risultati (ASP.NET MVC) o lo espone ad altri client (ASP.NET WebApi) –

7

Date un'occhiata al article da MSDN migliori pratiche.

Il codice sorgente dell'applicazione nell'articolo può essere trovato here.

21

Il mio consiglio è di creare classi separate chiamate "servizi". Inseriscili in un diverso progetto di libreria di classi (o spazio dei nomi) e rendili indipendenti sull'infrastruttura di framework MVC. Raccomando di utilizzare anche una sorta di iniezione di dipendenza (la migliore è l'iniezione del costruttore). Quindi le classi di servizio potrebbero essere:

public class MyService : IMyService 
{ 
    IFirstDependency _firstService; 
    ISecondDependency _secondService; 

    public MyService(IFirstDependency firstService, ISecondDependency secondService) 
    { 
    } 

    public Result DoStuf(InputDTO) 
    { 
     // some important logic   
    } 
} 

Quindi si consumano questi servizi dai controller. Look here per un esempio completo.

Secondo repository - il mio consiglio è di non usarli se si utilizzerà un moderno ORM (NHibernate, EntityFramework), perché la logica aziendale verrà incapsulata nel livello di servizio e il database sarà già incapsulato con il Quadro ORM.

+1

Penso che il problema con il saltare la sezione repository e andare a destra verso l'ORM sia che le classi di servizio ottengano direttamente il contesto ORM, il che significa che tutte quelle classi nel tuo servizio avranno accesso a tutte le tabelle che hai inserito nel contesto invece di classe di servizio che funziona solo con le tabelle di cui ha bisogno. Potresti evitarlo passando DbSet nel ctor di ogni classe e risolvendolo con DI ma potresti incorrere in problemi con questo? – user441521

6

Citando “Business logic should be in a service, not in a model”?:

In un MVP/MVC/MVVM/MV * architettura, servizi non esistono affatto. O se lo fanno, il termine è usato per riferirsi a qualsiasi oggetto generico che può essere iniettato in un controller o in un modello di vista. La logica aziendale è nel tuo modello. Se vuoi creare "oggetti di servizio" per orchestrare operazioni complicate, questo è visto come un dettaglio di implementazione. Un sacco di gente, purtroppo, implementa MVC in questo modo, ma è considerato un anti-modello (Anemic Domain Model) perché il modello stesso non fa nulla, è solo un mucchio di proprietà per l'interfaccia utente.

Alcune persone pensano erroneamente che adottare un metodo di controllo a 100 linee e spingerlo tutto in un servizio faccia in qualche modo una migliore architettura. Davvero non lo è; tutto ciò che fa è aggiungere un altro strato, probabilmente non necessario, di indirezione. In pratica, il controller sta ancora facendo il lavoro, lo fa solo attraverso un oggetto "helper" mal chiamato. Consiglio vivamente la presentazione Wicked Domain Models di Jimmy Bogard per un chiaro esempio di come trasformare un modello di dominio anemico in uno utile. Implica un attento esame dei modelli che stai esponendo e quali operazioni sono effettivamente valide in un contesto aziendale.

Problemi correlati