Situación:
Tengo una dll con sus clases, métodos y acceso a base de datos (insertar, modificar y muestra por pantalla una determinada clase).Tengo que cambiar el acceso de base de datos por un acceso a un servicio web (que no hacemos nosotros)
El servicio web proporciona unos objetos que no se ajustan nuestras clases originales
Requisitos:
Que fuera una dll es significativo porque quiere decir que se usa por varias aplicaciones y por lo tanto la modificación de las clases debe tener el menor impacto posible .Solución:
- Para empezar duplique la dll existente cambiando el nombre al ensamblado
- Identifique los valores de nuestras tablas y propiedades con su correspondencia en el servicio web
- Quite el acceso a datos por las llamadas al servicio web
- Mi "problema" se complicó cuando comprobé que no sería todo tan sencillo:
- tendría aplicaciones que posiblemente hiciera consultas SQL a esas tablas (usando evidentemente el nombre de las columnas)
- El servicio web, me proporciona métodos para hacer la consultas, pero no pasando como parámetros un objeto sino lista de clave-valor , donde la calve era del tipo campo1,campo2.. (no me preguntéis porque esa codificación)
- A mis clases de entidad les añadí un atributo personalizado. Esto me permitía relacionar las tablas SQL con los parámetros del servicio web con un mínimo impacto.
Module miEjemplo
Public Sub Ejemplo()
Dim miSqlViejo = "select dni, nombre from personas "
For Each attribute As MiEntityAttribute In MiEntityAttribute.GetMiEntityAttribute(GetType(miClaseDecorada)).Values
If Not attribute Is Nothing Then
miSqlViejo = miSqlViejo.Replace(attribute.ColumnaOLD, attribute.ColumnaNew)
End If
Next
Console.Write(miSqlViejo) 'select dni_cif, nombreCompleto from personas
End Sub
Public Class miClaseDecorada
Private _dni As String
Private _nombre As String
<MiEntity("dni", "dni_cif")>
Public Property DNI() As String
Get
Return _dni
End Get
Set(ByVal value As String)
_dni = value
End Set
End Property
<MiEntity("nombre", "nombreCompleto")>
Public Property Nombre() As String
Get
Return _nombre
End Get
Set(ByVal value As String)
_nombre = value
End Set
End Property
End Class
''' <summary>
''' Atributos personales
''' </summary>
''' <remarks></remarks>
<AttributeUsage(AttributeTargets.Property, AllowMultiple:=False)>
Friend Class MiEntityAttribute
Inherits Attribute
Private _columnaBDOLD As String
Private _columnaBDnew As String
Public Sub New()
End Sub
Public Sub New(columnaBDOLD As String, columnaBDnew As String)
Me._columnaBDOLD = columnaBDOLD
_columnaBDnew = columnaBDnew
End Sub
''' <summary>
''' Nombre de la propiedad dentro de la base de datos vieja
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Overridable ReadOnly Property ColumnaOLD() As String
Get
Return _columnaBDOLD
End Get
End Property
''' <summary>
''' Nombre de la propiedad dentro de la base de datos nueva
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Overridable ReadOnly Property ColumnaNew() As String
Get
Return _columnaBDnew
End Get
End Property
Friend Shared Function GetMiEntityAttribute(ByVal ot As Type) As Dictionary(Of String, MiEntityAttribute)
Dim oret As Dictionary(Of String, MiEntityAttribute) = New Dictionary(Of String, MiEntityAttribute)
For Each propiedad As PropertyInfo In ot.GetProperties()
If propiedad.GetCustomAttributes(GetType(MiEntityAttribute), False).Any() Then
oret.Add(propiedad.Name, CType(propiedad.GetCustomAttributes(GetType(MiEntityAttribute), False)(0), MiEntityAttribute))
Else
oret.Add(propiedad.Name, Nothing)
End If
Next
Return oret
End Function
End Class
End Module
Por supuesto pensé en un método "tradicional" : funciones para convertir objetos, enumerados que mantengan la relaciones entre las distintas propiedades…Pero el uso de los atributos me parece que da una solución sencilla y fácil de mantener.
Supongo que los trabajan con MVC el tema de los atributos lo tienen más que superado. Pero si eres de asp o de aplicaciones de escritorio, esto te facilita la vida con poco esfuerzo.
Supongo que los trabajan con MVC el tema de los atributos lo tienen más que superado. Pero si eres de asp o de aplicaciones de escritorio, esto te facilita la vida con poco esfuerzo.
Otra solución con interfaces :http://blog.koalite.com/2015/03/interfaces-marcadoras-atributos-y-convenciones/