2015-09-28 15 views
5

Sto creando un'applicazione multistrato, con un'applicazione asp.net mvc come livello più alto.Applicazione multilivello ASP.NET MVC: dove posizionare l'inizializzazione di Automapper?

l'architettura è la seguente (---> significa riferimenti):

Presentazione strato ---> Livello Servizio ---> strato Attività ----> strato di accesso ai dati ----> Database

Inoltre, esiste un livello denominato "Infrastruttura" a cui fanno riferimento tutti i livelli.

Ogni livello ha le proprie entità. Ad esempio: nel livello di presentazione potremmo avere UserViewModel, nel livello di servizio UserDTO, nel livello aziendale UserBDO e, infine, nel livello di accesso ai dati, Utente.

Il automapper viene utilizzato per automatizzare la conversione tra diversi tipi.

Ho letto che alcuni sviluppatori suggeriscono di posizionare la creazione dei mapping in Global.asax, ma è ovvio che se si dispone di un'applicazione multistrato non è possibile creare tutti i mapping lì. Non puoi mappare Utente con UserBDO nel livello di presentazione.

Quindi, sto chiedendo il modo più pulito per gestire la centralizzazione del mapping in un'applicazione multilayred. Puoi persino suggerire cambiamenti nell'architettura.

+0

avete un livello come utility o framework, lì è possibile esporre una funzione che può digitare fromTYPE e TOTYPE e convertire – Rex

+0

È necessario un progetto di utilità o qualcosa di simile. Dove tieni le tue enumerazioni (nomenclature)? –

+0

@Vinary Singh Quindi, stai suggerendo di cambiare l'architettura? Il livello aziendale non può fare riferimento a tutti i tipi, ma solo a UtenteBDO e Utente. Non conosce UserDTO e UserViewModel. –

risposta

1

Ti suggerisco di avere già la risposta - se non riesci ad accedere a tutti i tipi in un unico posto - dividi le configurazioni di mappatura in più parti. Questa soluzione è più gestibile in progetti di grandi dimensioni (basta immaginare 100 o 1000 mapping in una configurazione). Ad esempio, utilizziamo un mapper specifico per convertire i contratti WCF di terze parti in DTO personalizzati. Questo mappatore si trova in un progetto separato insieme al client WCF. Quindi i contratti e le mappature non sono accessibili dall'esterno.

+0

Quindi, chiami i mapping nel costruttore della classe che convertirà un tipo in un altro? O hai un approccio diverso? –

+0

Sì, non chiamiamo direttamente i metodi 'Mapper'. Invece un class-wrapper è usato con il proprio metodo 'Map' (semplice wrapper per' Mapper.Map'). Questa classe ha anche un costruttore statico che contiene chiamate 'Mapper.CreateMap' (quindi siamo sicuri che la configurazione sia stata creata prima della chiamata a' Mapper.Map', e venga creata solo 1 volta). –

+0

Hai bisogno di tutti questi strati? Prova a iniziare in modo semplice con solo Entities e modelli/modelli di visualizzazione MVC. Prova a collassare i tuoi progetti in cartelle per utilizzare invece gli spazi dei nomi. Lo fai perdendo qualcosa di significativo. L'utilizzo di automapper in un progetto greenfield è solitamente un'indicazione che le cose sono già troppo complesse. – DalSoft

0

Cerco di rispondere alla mia domanda: sentitevi liberi di correggermi se c'è qualcosa che non vi suona bene.

userò le parole seguenti:

  • strato: in questo contesto uno strato è un modulo dell'applicazione in senso verticale (dal database all'interfaccia utente)

  • modulo : una zona della vostra applicazione in senso orizzontale, ad esempio "CRM", "prodotto", contabile", ... ognuno con è il codice in diversi strati

Se yo. hai un'applicazione divisa in n layer e n moduli, il follwing potrebbe essere un esempio per una classe specifica di un particolare modulo e layer.

public static class ProductMapper 
{ 
    static ProductMapper() 
    { 
     MapProductBDOToDTO(); 
     MapProductDTOToBDO(); 

     MapProductCategoryBDOToDTO(); 
     MapProductCategoryDTOToBDO(); 

     MapIvaBDOToDTO(); 
     MapIvaDTOToBDO(); 

     MapProductSupplierBDOToDTO(); 
     MapProductSupplierDTOToBDO(); 

     MapProductPictureBDOToDTO(); 
     MapProductPictureDTOToBDO(); 

     MapProductNoteBDOToDTO(); 
     MapProductNoteDTOToBDO(); 

     MapStockProductBDOToDTO(); 
     MapStockProductDTOToBDO(); 

     MapTagBDOToDTO(); 
     MapTagDTOToBDO(); 
    } 


    public static TTargetType Convert<TToConvert, TTargetType>(TToConvert toConvert) 
    { 
     return Mapper.Map<TTargetType>(toConvert); 
    } 


    private static void MapProductDTOToBDO() 
    { 
     Mapper.CreateMap<ProductDTO, ProductBDO>(); 
    } 

    private static void MapProductBDOToDTO() 
    { 
     Mapper.CreateMap<ProductDTO, ProductBDO>().ReverseMap(); 
    } 

    private static void MapProductCategoryDTOToBDO() 
    { 
     Mapper.CreateMap<ProductCategoryDTO, ProductCategoryBDO>(); 
    } 

    private static void MapProductCategoryBDOToDTO() 
    { 
     Mapper.CreateMap<ProductCategoryBDO, ProductCategoryDTO>(); 
    } 

    private static void MapIvaDTOToBDO() 
    { 
     Mapper.CreateMap<IvaDTO, IvaBDO>(); 
    } 

    private static void MapIvaBDOToDTO() 
    { 
     Mapper.CreateMap<IvaBDO, IvaDTO>(); 
    } 

    private static void MapProductSupplierDTOToBDO() 
    { 
     Mapper.CreateMap<ProductSupplierDTO, ProductSupplierBDO>(); 
    } 

    private static void MapProductSupplierBDOToDTO() 
    { 
     Mapper.CreateMap<ProductSupplierDTO, ProductSupplierBDO>().ReverseMap(); 
    } 

    private static void MapProductPictureDTOToBDO() 
    { 
     Mapper.CreateMap<ProductPictureDTO, ProductPictureBDO>(); 
    } 

    private static void MapProductPictureBDOToDTO() 
    { 
     Mapper.CreateMap<ProductPictureDTO, ProductPictureBDO>().ReverseMap(); 
    } 

    private static void MapProductNoteDTOToBDO() 
    { 
     Mapper.CreateMap<ProductNoteDTO, ProductNoteBDO>(); 
    } 

    private static void MapProductNoteBDOToDTO() 
    { 
     Mapper.CreateMap<ProductNoteDTO, ProductNoteBDO>().ReverseMap(); 
    } 

    private static void MapStockProductDTOToBDO() 
    { 
     Mapper.CreateMap<StockProductDTO, StockProductBDO>(); 
    } 

    private static void MapStockProductBDOToDTO() 
    { 
     Mapper.CreateMap<StockProductDTO, StockProductBDO>().ReverseMap(); 
    } 

    private static void MapTagDTOToBDO() 
    { 
     Mapper.CreateMap<TagDTO, TagBDO>(); 
    } 

    private static void MapTagBDOToDTO() 
    { 
     Mapper.CreateMap<TagDTO, TagBDO>().ReverseMap(); 
    } 

Come si può vedere si tratta di una classe statica con un costruttore statico, il che significa che il costruttore si chiamerà, non più di una volta durante il tempo di vita delle applicazioni. La prima volta che si chiama il metodo Convert, viene chiamato il costruttore e vengono creati tutti i mapping. La seconda, la terza, la quarta ... n volta si calerà il metodo Convert durante la stessa sessione, il costruttore non verrà chiamato.

Vantaggi:

  • Una mappatura particolare, non è possibile creare più di una volta
  • mappature vengono creati solo quando ne avete bisogno (in questo caso, quando si lavora con i prodotti). Non creare 1000 mapping all'avvio dell'applicazione per poi utilizzarne solo 5 o 6.

Svantaggi:

  • Uno sviluppatore può chiamare il metodo Convert generico con tutti i tipi di lui/lei vuole, tipi non vengono controllati. Tra l'altro, l'utilizzo di un metodo generico richiede meno codice e, se i mapping non sono stati ancora creati, l'AutoMapper genera un'eccezione.
Problemi correlati