2011-07-30 17 views
17

He estado buscando un poco de API de escalamiento fluido para mapear objeto-objeto, similar a AutoMapper. ¿Existen herramientas en Scala?¿Hay algo así como AutoMapper para Scala?

+1

Mientras mira hacia arriba AutoMapper Corrí en esta publicación SO: [Automapper para Java?] (http://stackoverflow.com/questions/3319002/automapper-for-java) que menciona algunas posibilidades, incluyendo [Dozer] (http://dozer.sourceforge.net /). No necesariamente "Scala", pero ... –

+2

En este momento, alguien ya debe haber comenzado a desarrollar uno en Scala ... – mrcaramori

+0

Nada existe para Scala que yo sepa. Planeo escribir una API de mapeo de propiedades para [ModelMapper] (http://modelmapper.org) que aproveche mejor algunas de las características de Scala, pero por ahora ciertamente puede usar ModelMapper como lo hace para Java. – Jonathan

Respuesta

12

Creo que hay menos necesidad de algo como AutoMapper en Scala, porque si usa los modelos idiomáticos de Scala es más fácil escribir y manipular y porque puede definir aplanamiento/proyección fácilmente automático usando conversiones implícitas.

Por ejemplo, aquí es el equivalente en Scala de 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: No debería utilizar doble para cantidades de dinero ...

1

Para asignaciones complejas que uno puede desear considerar basado en Java cartógrafos como

objetos Scala se puede acceder desde Java:

Implementaciones de conversiones implícitas para objetos complejos sería más suave con asignaciones declarativas de handcrafted unos.

encontrado una lista más larga aquí:

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

4

Estoy de acuerdo con @paradigmatic, es cierto que el código será mucho más limpia usando Scala, pero a veces puede encontrarse el mapeo entre clases de casos que se ven muy similar, y eso es solo un desperdicio de teclas.

He empezado a trabajar en un proyecto para resolver los problemas, se puede encontrar aquí: https://github.com/bfil/scala-automapper

Se utiliza macros para generar las asignaciones para usted.

Por el momento puede mapear una clase de caso a un subconjunto de la clase de caso original, maneja opcionales y campos opcionales, así como otras cosas menores.

Todavía estoy tratando de descubrir cómo diseñar la API para admitir el cambio de nombre o el mapeo de campos específicos con lógica personalizada, cualquier idea o comentario sería muy útil.

Se puede utilizar para algunos casos simples en este momento, y por supuesto si la asignación es muy compleja, podría ser mejor definir la asignación manualmente.

La biblioteca también permite definir manualmente Mapping tipos entre las clases de casos en cualquier caso, que puede ser proporcionado como un parámetro implícito a un método AutoMapping.map(sourceClass) o sourceClass.mapTo[TargetClass].

ACTUALIZACIÓN

He acaba de lanzar una nueva versión que maneja iterables, Maps y permite pasar de asignaciones dinámicas (para apoyar el cambio de nombre y la lógica personalizada por ejemplo)

Cuestiones relacionadas