2012-08-16 10 views
17

Estamos utilizando DTO como contratos de datos en nuestro servicio web WCF. El objetivo de estos DTO es exponer solo la información relevante para un método API específico.Cómo organizar y nombrar DTO que se usan como Contratos de datos en un servicio web de WCF

Lo que estoy buscando de ustedes es un consejo sobre las mejores prácticas aquí.

Por ejemplo, considere el siguiente modelo simple:

class Order 
{ 
    int CreatedBy { get; set; } 
    DateTime CreatedOn { get; set; } 
    string Description { get; set; } 
    int Id { get; set; } 
    string Name { get; set; } 
} 

Asumiendo nuestra API permite a un consumidor Crear, actualización y Obtener una Orden, hemos creado los siguientes dtos. Los atributos DataMember y DataContract se eliminan por simplicidad.

Crear método: Un usuario no puede especificar el Id y CreatedOn propiedades, por lo que el DTO se ve así:

class CreateOrderData 
{ 
    int CreatedBy { get; set; } 
    string Description { get; set; } 
    string Name { get; set; } 
} 

actualización método: Un usuario no puede especificar el Id , CreatedOn y CreatedBy propiedades, por lo que el DTO se ve así:

class UpdateOrderData 
{ 
    string Description { get; set; } 
    string Name { get; set; } 
} 

Obtener método: Un usuario debe ser capaz de ver todo de la Orden, por lo que el DTO se ve así:

class OrderData 
{ 
    int CreatedBy { get; set; } 
    DateTime CreatedOn { get; set; } 
    string Description { get; set; } 
    int Id { get; set; } 
    string Name { get; set; } 
} 

Así que aquí están mis preguntas:

  • Suponiendo que hay más propiedades en el modelo de Pedido y muchas de esas propiedades se comparten entre los DTO "Crear" y "Actualizar", ¿tiene sentido que estas clases se extiendan desde una clase base común? En caso afirmativo, ¿el DTO "Obtener" (OrderData) también se extiende desde esa clase? Si hacemos eso, ¿no deja estos DTO demasiado dependientes el uno del otro?

  • Si todas las propiedades son comunes entre las DTO "Crear" y "Actualizar", ¿deberíamos crear dos DTO diferentes? ¿Si es así por qué? Si no, (esto es solo una pregunta de nombres ahora) ¿a qué se debe llamar el DTO "CreateOrUpdate" para que el nombre sea obviamente diferente del DTO "Get"?

  • ¿Es correcto sumar todos los DTO con algo como "Datos" u "DataObject" o "Dto"?

  • ¿Estamos en el camino correcto aquí? Si no, ¿cómo se puede mejorar este diseño?

Actualización:

Creo que no me gusta la herencia en dtos porque la clase base también estará expuesto en el WSDL y el cliente será capaz de ver y instanciarlo que parece sucia para mí (mira esto: WCF Serialization with object inheritance?). ¿Qué tal el uso de interfaces en DTO para hacer cumplir las propiedades comunes en lugar de la herencia? Como los DTO no deberían tener ningún comportamiento en ellos, no estamos perdiendo mucho reemplazando la herencia.

+1

+1 Creo que es una preferencia personal. Cuando me encuentro en este situación tiendo a ir a la clase base o combinar ambos en uno e ir por el nombre 'Upsert'. Dejaría fuera cualquier sufijo como la notación húngara' dto' ya que puede identificar fácilmente el tipo y en mi humilde opinión es mejor usar el espacio de nombres como 'Project.Data.DataObjects' en lugar de suffix. Solo mis 2 centavos –

+0

Gracias por su respuesta Jeremy. Estoy de acuerdo en que la mayor parte es una preferencia personal, pero aún me gustaría que alguien valide estas preguntas y preocupaciones y presente algunos argumentos con respecto a las mejores prácticas y las posibles dificultades. Además, si lo entiendo correctamente, Upsert debería significar "actualizar si está presente e insertar si no". Si bien es un pensamiento interesante, no es la intención de estas API. Los consumidores de estas API sabrán específicamente cuándo Insertar o Actualizar. –

Respuesta

5

Dado que este es mucho acerca de las preferencias personales, yo haría esto ..

  1. yo no crear una clase base común, ya que no se adheriría a L en sólido. Si le preocupa DRY, puede crear una agregación en su lugar.

  2. Si todas las propiedades son comunes, entonces tiene sentido crear un Guardar que tome ese objeto, el orden Dto clase tendrá una propiedad clave (es) que indicaría si es un pedido existente o no.

  3. Sufriría todo con Dto, porque muchos nombres de clases Dto son los mismos que las clases de dominio, se vuelven confusos ya que existirán en el mismo método. A continuación, se puede decorar sus dtos con DataContract (Name = "orden", espacio de nombres = "htp: // sudominio/.."..] De esta manera estarán expuestos al mundo exterior de acuerdo a sus preferencias

He estado en múltiples proyectos que usan la misma arquitectura general, generalmente uso AutoMapper para asignar dtos a un dominio. Me ha funcionado muy bien!

+0

Me gustan sus sugerencias, especialmente su mención del principio SOLIDO y la clase base común. Con respecto a AutoMapper, lo he usado en el pasado y me gustó, pero como nuestros objetos no son tan complejos, estamos usando métodos de extensión para las conversiones. –

Cuestiones relacionadas