2011-07-30 9 views
17

Sono stato alla ricerca di alcune API scala fluente per il mapping dell'oggetto-oggetto, simile a AutoMapper. Esistono questi strumenti in Scala?C'è qualcosa come AutoMapper per Scala?

+1

durante la ricerca mi sono imbattuto automapper in questo post SO: [Automapper per Java?] (http://stackoverflow.com/questions/3319002/automapper-for-java) che menziona alcune possibilità, tra cui [Dozer] (http://dozer.sourceforge.net /). Non necessariamente "Scala", ma ... –

+2

A questo punto, qualcuno deve aver già iniziato a svilupparne uno in Scala ... – mrcaramori

+0

Non esiste nulla per Scala che io conosca. Ho in programma di scrivere un'API di mappatura delle proprietà per [ModelMapper] (http://modelmapper.org) che sfrutta meglio alcune delle funzionalità di Scala, ma per ora puoi certamente usare ModelMapper come per Java. – Jonathan

risposta

12

Penso che ci sia meno bisogno di qualcosa come AutoMapper in Scala, perché se si usano i modelli Scala idiomatici sono più facili da scrivere e manipolare e perché è possibile definire facilmente l'appiattimento/proiezione automatico utilizzando le conversioni implicite.

Per esempio qui è l'equivalente in Scala di automapper flattening example:

// The full model 

case class Order(customer: Customer, items: List[OrderLineItem]=List()) { 
    def addItem(product: Product, quantity: Int) = 
    copy(items = OrderLineItem(product,quantity)::items) 
    def total = items.foldLeft(0.0){ _ + _.total } 
} 

case class Product(name: String, price: Double) 

case class OrderLineItem(product: Product, quantity: Int) { 
    def total = quantity * product.price 
} 

case class Customer(name: String) 

case class OrderDto(customerName: String, total: Double) 


// The flattening conversion 

object Mappings { 
    implicit def order2OrderDto(order: Order) = 
    OrderDto(order.customer.name, order.total) 
} 


//A working example 

import Mappings._ 

val customer = Customer("George Costanza") 
val bosco = Product("Bosco", 4.99) 
val order = Order(customer).addItem(bosco, 15) 

val dto: OrderDto = order // automatic conversion at compile-time ! 

println(dto) // prints: OrderDto(George Costanza,74.85000000000001) 

PS: non dovrei usare Doppio prezzo ammonta ...

1

Per mappature complesse si può prendere in considerazione basato su Java mapper come

oggetti Scala si può accedere da Java:

implementazioni di conversioni implicite per oggetti complessi sarebbe più agevole con mappature dichiarativi di Handcrafted quelli.

Trovato un elenco più qui:

http://www.javacodegeeks.com/2013/10/java-object-to-object-mapper.html

4

Sono d'accordo con @paradigmatic, è vero che il codice sarà molto più pulito utilizzando Scala, ma a volte si può trovare se stessi mapping tra classi case che sembrano molto simile, e questo è solo uno spreco di tasti.

ho iniziato a lavorare su un progetto per affrontare le questioni, si può trovare qui: https://github.com/bfil/scala-automapper

Esso utilizza le macro per generare le mappature per voi.

Al momento è possibile associare una classe di case a un sottoinsieme della classe case originale, gestisce gli optionals, campi facoltativi e altre cose minori.

Sto ancora cercando di capire come progettare l'api per supportare la ridenominazione o la mappatura di campi specifici con logica personalizzata, qualsiasi idea o input su questo sarebbe molto utile.

Al momento può essere utilizzato per alcuni casi semplici e, naturalmente, se la mappatura diventa molto complessa, potrebbe essere meglio definire manualmente la mappatura.

La libreria consente inoltre di definire manualmente i tipi Mapping tra classi di casi che possono essere forniti come parametro implicito in un metodo AutoMapping.map(sourceClass) o sourceClass.mapTo[TargetClass].

UPDATE

Ho appena rilasciato una nuova versione che gestisce iterabili, Maps e permette di passare in mappature dinamiche (per supportare la ridenominazione e logica personalizzata per esempio)