Grimpi IT Blog

mayo 28, 2011

VAN de Pex, Moles & Code Contracts

Filed under: .NET, Pex, Test Driven Development — grimpi @ 4:26 pm

Hoy a las 18 GMT, voy a presentar en ALT.NET Hispano una VAN de Unit Testing con Pex, Moles y Code Contracts.

Para acceder, pueden hacerlo por live meeting mediante alguno de los siguientes enlaces:

http://snipr.com/virtualaltnet

https://www323.livemeeting.com/cc/usergroups/join?id=van&role=attend

Para el que nunca escuchó hablar de estas tecnologías, esta es la web oficial de Pex.

Desde este link se pueden bajar el PPT de la Presentación que voy a hacer.

marzo 3, 2011

Herramientas fundamentales para el desarrollo:

Filed under: .NET, Links — grimpi @ 12:01 pm

  • Notepad++. Es el excelente reemplazo al famoso UltraEdit, pero open source. Indispensable.
  • HeidiSQL: No se si es la mejor IDE de MySql gratuita que existe, pero le pega en palo. Lo mejor de todo, es que es un solo archivo .exe. No tiene dependencias ni dll ni requiere instalación.
  • .NET Reflector: De Red Gate. La mejor herramienta de reflector para .net. Hay que aprovechar a bajarla ahora, porque es gratis solo hasta el 30 de mayo del 2011.
  • Visual Studio Productivity Power Tools: Es un Add-In para Visual Studio con algunas boludeses que nos mejorar la calidad de vida. Recomendado.
  • ReSharper: No es gratis, pero para mi es fundamental. Se puede conseguir legalmente gratis si demostramos que participamos de algún proyecto open source.
  • Open DBDiff: Para comparar bases de datos SQL Server :)
  • NuGet: Es un Add-in para el Visual Studio. Ya no es necesario buscar manualmente librerías y Add-Ins. Con NuGet la vida es mas sencilla. Así de simple.
  • PDFSharp: La mejor librería open source para generar PDF en .NET. No busque otra.
  • 7-Zip: No es una herramienta de desarrollo, sino un compresor de archivos. Pero siendo open source y comprimiendo mas cualquier otro formato, no entiendo como todavía hay gente que usa el WinRar (y ni hablar de los que usan WinZip…)
  • FileZilla: El mejor cliente de FTP que existió, existe y existirá. Y encima gratis. El que no este de acuerdo con esta afirmación, que no lea mas este blog :)
  • Dependency Explorer: Nos informa que dll y componentes le esta faltando a una aplicación. Es una herramienta de los 90. Usada mucho por los desarrolladores de Visual Basic 6 y tecnologías COM. Sin embargo, mucha veces la necesitamos hoy en día.
  • Selenium: Para testing de paginas web. Imperdible.
  • Firebug: Si no usamos Chrome, el mejor Add-in de Firefox para trabajar con Javascript, CSS, Ajax, etc…
  • Regular Expression Designer: No se si es la mejor, pero es una excelente herramienta para trabajar y testear expresiones regulares. Y Gratis.
  • AnkhSVN: Cliente de SVN para Visual Studio. No puedo decir que es una excelente herramienta, porque a veces lo puteo un poco. Pero es la que mejor se integra con Visual Studio.
  • WinMerge: Excelente herramienta para comparar archivos y directorios.
  • Compumap: Nada que ver el desarrollo ni bases de datos. Simplemente quería elogiar esta excelente herramienta para buscar colectivos en Buenos Aires. Incluso funciona en Windows 3.1!!!!!

enero 28, 2011

Que reglas usar en el Code Analysis de Visual Studio?

Filed under: .NET, Visual Studio — grimpi @ 12:46 pm

Cuando uno descubre FxCop, la excelente herramienta de analizador de código que viene integrada en el Visual Studio 2008 y 2010, enseguida tiende a creer que todo nuestro código para que sea optimo, no debe tener absolutamente ningún warning de FxCop.
Pero al poco tiempo nos damos cuenta que tal cosa es imposible y por varias razones. La primera es que la sugerencia no es valida, que el análisis del CodeAnalysis falló. Otras veces, que es realmente intranscendente y costoso hacer el cambio (especialmente las reglas agrupadas en la categoría “naming”).
Googleando un poco descubrí este excelente post de la gente de Microsoft, con un listado de todas las reglas que ellos usan para sus propios desarrollos y testeando, me pareció una muy buena selección de reglas.

Design
CA1008 EnumsShouldHaveZeroValue
CA1009 DeclareEventHandlersCorrectly
CA1011 ConsiderPassingBaseTypesAsParameters
CA1012 AbstractTypesShouldNotHaveConstructors
CA1014 MarkAssembliesWithClsCompliant
CA1017 MarkAssembliesWithComVisible
CA1018 MarkAttributesWithAttributeUsage
CA1019 DefineAccessorsForAttributeArguments
CA1023 IndexersShouldNotBeMultidimensional
CA1025 ReplaceRepetitiveArgumentsWithParamsArray
CA1026 DefaultParametersShouldNotBeUsed
CA1027 MarkEnumsWithFlags
CA1028 EnumStorageShouldBeInt32
CA1030 UseEventsWhereAppropriate
CA1032 ImplementStandardExceptionConstructors
CA1034 NestedTypesShouldNotBeVisible
CA1036 OverrideMethodsOnComparableTypes
CA1038 EnumeratorsShouldBeStronglyTyped
CA1039 ListsAreStronglyTyped
CA1040 AvoidEmptyInterfaces
CA1041 ProvideObsoleteAttributeMessage
CA1043 UseIntegralOrStringArgumentForIndexers
CA1044 PropertiesShouldNotBeWriteOnly
CA1045 DoNotPassTypesByReference
CA1046 DoNotOverloadOperatorEqualsOnReferenceTypes
CA1050 DeclareTypesInNamespaces
CA1051 DoNotDeclareVisibleInstanceFields
CA1052 StaticHolderTypesShouldBeSealed
CA1053 StaticHolderTypesShouldNotHaveConstructors
CA1054 UriParametersShouldNotBeStrings
CA1055 UriReturnValuesShouldNotBeStrings
CA1056 UriPropertiesShouldNotBeStrings
CA1057 StringUriOverloadsCallSystemUriOverloads
CA1058 TypesShouldNotExtendCertainBaseTypes
CA1059 MembersShouldNotExposeCertainConcreteTypes

Globalization
CA1300 SpecifyMessageBoxOptions
CA1301 AvoidDuplicateAccelerators
CA1304 SpecifyCultureInfo
CA1305 SpecifyIFormatProvider
CA1306 SetLocaleForDataTypes
CA1307 SpecifyStringComparison
CA1309 UseOrdinalStringComparison
CA2101 SpecifyMarshalingForPInvokeStringArguments

Interoperability
CA1401 PInvokesShouldNotBeVisible
CA1402 AvoidOverloadsInComVisibleInterfaces
CA1403 AutoLayoutTypesShouldNotBeComVisible
CA1404 CallGetLastErrorImmediatelyAfterPInvoke
CA1405 ComVisibleTypeBaseTypesShouldBeComVisible
CA1406 AvoidInt64ArgumentsForVB6Clients
CA1408 DoNotUseAutoDualClassInterfaceType
CA1413 AvoidNonpublicFieldsInComVisibleValueTypes

Naming
CA1700 DoNotNameEnumValuesReserved
CA1701 ResourceStringCompoundWordsShouldBeCasedCorrectly
CA1702 CompoundWordsShouldBeCasedCorrectly
CA1703 ResourceStringsShouldBeSpelledCorrectly
CA1704 IdentifiersShouldBeSpelledCorrectly
CA1707 IdentifiersShouldNotContainUnderscores
CA1708 IdentifiersShouldDifferByMoreThanCase
CA1709 IdentifiersShouldBeCasedCorrectly
CA1710 IdentifiersShouldHaveCorrectSuffix
CA1711 IdentifiersShouldNotHaveIncorrectSuffix
CA1712 DoNotPrefixEnumValuesWithTypeName
CA1713 EventsShouldNotHaveBeforeOrAfterPrefix
CA1714 FlagsEnumsShouldHavePluralNames
CA1715 IdentifiersShouldHaveCorrectPrefix
CA1716 IdentifiersShouldNotMatchKeywords
CA1719 ParameterNamesShouldNotMatchMemberNames
CA1720 IdentifiersShouldNotContainTypeNames
CA1721 PropertyNamesShouldNotMatchGetMethods
CA1722 IdentifiersShouldNotHaveIncorrectPrefix
CA1724 TypeNamesShouldNotMatchNamespaces

Performance
CA1811 AvoidUncalledPrivateCode
CA1812 AvoidUninstantiatedInternalClasses
CA1813 AvoidUnsealedAttributes
CA1815 OverrideEqualsAndOperatorEqualsOnValueTypes
CA1816 DisposeMethodsShouldCallSuppressFinalize
CA1819 PropertiesShouldNotReturnArrays

Portability
CA1900 ValueTypeFieldsShouldBePortable
CA1901 PInvokeDeclarationsShouldBePortable

Reliability>

CA2001 AvoidCallingProblematicMethods
CA2002 DoNotLockOnObjectsWithWeakIdentity
CA2004 RemoveCallsToGCKeepAlive
CA2006 UseSafeHandleToEncapsulateNativeResources>

Security
CA2102 CatchNonClsCompliantExceptionsInGeneralHandlers
CA2103 ReviewImperativeSecurity
CA2104 DoNotDeclareReadOnlyMutableReferenceTypes
CA2105 ArrayFieldsShouldNotBeReadOnly
CA2106 SecureAsserts
CA2107 ReviewDenyAndPermitOnlyUsage
CA2108 ReviewDeclarativeSecurityOnValueTypes
CA2109 ReviewVisibleEventHandlers
CA2111 PointersShouldNotBeVisible
CA2112 SecuredTypesShouldNotExposeFields
CA2114 MethodSecurityShouldBeASupersetOfType
CA2115 CallGCKeepAliveWhenUsingNativeResources
CA2116 AptcaMethodsShouldOnlyCallAptcaMethods
CA2117 AptcaTypesShouldOnlyExtendAptcaBaseTypes
CA2118 ReviewSuppressUnmanagedCodeSecurityUsage
CA2119 SealMethodsThatSatisfyPrivateInterfaces
CA2120 SecureSerializationConstructors
CA2121 StaticConstructorsShouldBePrivate
CA2122 DoNotIndirectlyExposeMethodsWithLinkDemands
CA2123 OverrideLinkDemandsShouldBeIdenticalToBase
CA2124 WrapVulnerableFinallyClausesInOuterTry
CA2126 TypeLinkDemandsRequireInheritanceDemands
CA2127 SecurityTransparentAssembliesShouldNotContainSecurityCriticalCode
CA2128 SecurityTransparentCodeShouldNotAssert
CA2129 SecurityTransparentCodeShouldNotReferenceNonpublicSecurityCriticalCode

Usage
CA1806 DoNotIgnoreMethodResults
CA2207 InitializeValueTypeStaticFieldsInline
CA2208 InstantiateArgumentExceptionsCorrectly
CA2209 AssembliesShouldDeclareMinimumSecurity
CA2211 NonConstantFieldsShouldNotBeVisible
CA2213 DisposableFieldsShouldBeDisposed
CA2214 DoNotCallOverridableMethodsInConstructors
CA2216 DisposableTypesShouldDeclareFinalizer
CA2217 DoNotMarkEnumsWithFlags
CA2218 OverrideGetHashCodeOnOverridingEquals
CA2220 FinalizersShouldCallBaseClassFinalizer
CA2221 FinalizersShouldBeProtected
CA2224 OverrideEqualsOnOverloadingOperatorEquals
CA2225 OperatorOverloadsHaveNamedAlternates
CA2227 CollectionPropertiesShouldBeReadOnly
CA2228 DoNotShipUnreleasedResourceFormats
CA2229 ImplementSerializationConstructors
CA2230 UseParamsForVariableArguments
CA2233 OperationsShouldNotOverflow
CA2234 PassSystemUriObjectsInsteadOfStrings
CA2235 MarkAllNonSerializableFields
CA2236 CallBaseClassMethodsOnISerializableTypes
CA2237 MarkISerializableTypesWithSerializable
CA2240 ImplementISerializableCorrectly

diciembre 17, 2010

Como hacer unit testing contra la base de datos?

Filed under: .NET, Arquitectura, Mocks, Test Driven Development — grimpi @ 6:30 pm

Hoy en día el desarrollo de software, no se concibe si unit testing. Hasta el famoso “Hola Mundo” debe tener su respectiva clase de testing…
Uno de los principales problemas que surge a la hora de crear los test unitarios, es como probar contra la base de datos.
Donde está el problema? Supongamos que hacemos un test unitario “Login” que valide el usuario con una password incorrecta ingresada a propósito para ver falla el login. Y supongamos que en la lógica de negocio, al tercer intento fallido de login se bloquee el usuario.
Que va a pasar si tenemos otro test unitario, que intenta probar el login exitoso si ya testeamos tres veces el test unitario anterior? Va a fallar, porque en la base de datos, el usuario quedo marcado como bloqueado.

Para ser más claro, si nuestros test unitarios “ensucian” la base de datos, existe una gran posibilidad de que fallen y no por culpa de que están mal escritos o hay un bug en el código, sino porque los datos no son los que esperamos que fuesemos.

Para solucionar este problema, existen diversas técnicas:

  • Resetear los datos de la base de datos antes de cada tests.
  • Hacer que el test corra dentro de una transacción distribuida y luego hacer un rollback de la transacción.
  • Resetear solo los datos usados por el test, después de que este haya corrido.
  • Usar mecanismo de versionado de datos incorporados en las nuevas versiones de SQL Server o Oracle (flashback tables).
  • Separar el test unitario de la base de datos (mocks).

Obviamente cada una de estas técnicas, tienen sus respectivas ventajas y desventajas. Vamos a empezar de la simple, a la más compleja.

Resetear los datos de la base de datos antes de cada tests.
Esta es la primera opción que viene a la mente. La principal ventaja es su facilidad de implementación.
Una opción practica para hacer esto es tener un backup de la base de datos “limpio” y restorearlo cada vez que se ejecuta un unit testing.
Otra opción es tener un set de datos especifico necesario para el testeo y cargarlo manualmente. Luego del testo, estos datos son reseteados. Existen frameworks como NDbUnit (hhttp://code.google.com/p/ndbunit/) o TDUnit (http://tdunit.codeplex.com/) que nos facilitan enormemente esta tarea. Básicamente funcionan configurando un xml de datos y llamando a una instrucción de carga de datos en cada test unitario.

Ejemplo de código con NDBUnit:

public void Test()
{
string connectionString = “server=localhost;user=dbuser;password=dbpassword;initial catalog=MyDatabase;” ;
NDbUnit.Core.INDbUnitTest mySqlDatabase = new
NDbUnit.Core.SqlClient.SqlDbUnitTest(connectionString);

mySqlDatabase.ReadXmlSchema(@”..\..\MyDataset.xsd”);
mySqlDatabase.ReadXml(@”..\..\MyTestdata.xml”);
}

La principal desventaja de este sistema es obvia. Performance. Limpiar y cargar los datos por cada test unitario, puede ser algo extremadamente costoso en cuanto a tiempos.

Hacer que el test corra dentro de una transacción y luego hacer un rollback de la transacción

Este mecanismo es tentadoramente simple, sin embargo, pocas personas lo deben usar.
Cada test que se corre, está dentro de una transacción distribuida (COM+) que al finalizar, hacemos un rollback. De esta manera extremadamente simple, mantenemos el estado de los datos de la base de datos en cada test.
El problema de este enfoque, es que las transacciones distribuidas son las lentas que las locales. Por otro lado, en determinados entornos, hacer que las transacciones distribuidas funciones, requieren de cierta configuración de Windows.
Existe una extensión para NUnit llamada XtUnit, que entre otras cosas, permite ponerle el atributo [Rollback] al método de testing y automáticamente este unit testing va a correr dentro de una transacción distribuida sin necesidad de que tengamos que escribir código adicional.

Ejemplo de Test con XtUnit:

[Test,DataRollBack]

public void Insert()

{

CustomerService custom = new
CustomerService();

custom.add(“Esteban”,29,21452367);

}

Ejemplo de test sin NUnit solo:

[Test]
public void Insert()
{
using (TransactionScope scope = new TransactionScope())
{
CustomerService custom = new
CustomerService();

custom.add(“Esteban”,29,21452367);
scope.rollback();
}
}

Resetear solo los datos usados por el test, después de que este haya corrido

Este enfoque evita tener que resetear toda la base de datos antes de que el test sea ejecutado. En cambio, se carga una serie de comandos típicamente de insert/delete antes y después de cada test. Las buenas noticias es que de esta manera el menor el trabajo adicional que se ejecuta y por lo tanto, mejora significativamente la performance.
El problema de esta técnica, es que uno debe conocer con antelación que datos va a necesitar el test y si nos olvidamos de insertar un dato necesario, puede que falle el test unitario no por un bug o error de diseño, sino por un simple olvido a la hora de insertar un registro en una tabla antes de que sea ejecutado el test.

Usar mecanismo de versionado de datos incorporados en las nuevas versiones de SQL Server o Oracle

Este es un enfoque bastante interesante y que nos ahorra escribir código. Las últimas versiones de las bases de datos modernas, incorporan la capacidad de hacer versionado de datos sobre las tablas. Cada vez que se hace un insert/update/delete, el dato anterior es guardado en otra tabla interna del motor con un timestamp, existiendo la posibilidad más adelante de consultar el estado de los datos en un momento determinado y de volver la tabla a ese estado.
En Oracle esta característica se llaman Flashback table y en SQL Server Change Tracking.
La ventaja de esta técnica es que no tengo que escribir manualmente el reseteado de los datos ni tengo que lidiar con transacciones distribuidas. Sin embargo, las desventajas son múltiples. En primer lugar, esta técnica solo funciona con las versiones más modernas de las bases de datos Oracle, SQL Server y Postgres. Por ejemplo, no sería posible hacerlo con SQL Server 2005. MySQL en ninguna versión tiene esta característica. Por otra parte, habilitar esta opción en la base de datos tiene un altísimo impacto en performance y en tamaño en disco. Por último, para habilitar esta opción, hay que hacerlo desde el motor de la base de datos.
Para pesar de todas estas desventajas, creo que es una técnica útil en determinados casos puntuales. Especialmente en situaciones donde no tenemos tiempo o no podemos escribir código.

Separar el test unitario de la base de datos (mocking)

Aquí presentamos la opción supuestamente “correcta” de la industria actualmente. Evitar a toda costa el test unitario contra la base de datos y reemplazarlo por mocks, que son clases que emulan el comportamiento de una base de datos (o de cualquier otra cosa que queramos, como web services por ejemplo), de tal manera que podemos probar si el método funciona como deseamos sin conectarse con la BD.
Existen varios frameworks de mocking (NMocks, Rhino, Typemock y Moq). En general son bastante parecidos en cuanto a funcionalidades básicas, aunque algunos son un poco más claros que otros. Personalmente me siento más cómodo trabajando con Moq.

Usar mocking como método de testeo unitario en reemplazo de la base de datos tiene varias ventajas. La primera es la velocidad. No es lo mismo ejecutar 300 test unitarios contra la BD que contra clases en memoria.

La segunda ventaja es la inmutabilidad de los datos. Al no correr contra una base de datos, no se modifica realmente ningún dato, lo que permite que se pueda simular siempre el mismo estado. Para esto es necesario que se cargue al objeto mock con el que se prueba, los valores iniciales que se necesitan, para que el test unitario no falle. O sea, el uso de mocking nos evita todos los problemas que vimos en las 4 soluciones del anterior post.

El uso de mocking también agrega mas previsibilidad al test unitario, cuando no tenemos mucho control sobre la fuente contra la que se prueba o esta tiene un comportamiento indeterminado, como por ejemplo, un monitor de red que prueba x tipo de paquetes. Son situaciones muy específicas y puntuales, pero en esos casos el uso de mocking resulta casi indispensable.

Pero este enfoque también tiene sus desventajas. En primer lugar, no es una prueba “real”. Es una simulación. Hay situaciones en las que un test unitario contra un mock puede resultar exitoso, pero en un escenario más real, contra la base de datos, puede que falle. Por ejemplo, en el caso de que un método llame un store procedure y devuelva determinado conjunto de datos. Si el store procedure fue por cuestiones de negocio modificado sin nuestro conocimiento de tal manera, que el resultado de salida cambie, si probamos contra el mock nunca nos vamos a enterar de esta modificación.

También puede darse el caso de que haya cambios en la estructura de una tabla o falten permisos. Todas situaciones que si no tenemos aviso, podrían hacer que el test unitario corra exitosamente cuando no debería.

Otra desventaja de esta técnica, es que no es inerte a como está el código de la aplicación. Para ser más claro, para que una clase de nuestra aplicación, sea “mockeable” debe estar programada para esto.

Debe estar hecha de tal manera, que uno pueda inyectar instancias distintas. Uno puede decir y de manera bastante correcta, que es una buena práctica que las clases permitan inyección de código. Puede ser, pero también es discutible. Depende de las características de la aplicación.

Pero el caso es que uno no puede mockear una clase si no pensó antes en que iba a usar esta técnica de test unitario. Claro que si uno trabaja con TDD no tenga este tipo de problemas, pero no todo el mundo trabaja así y ni tiene porque hacerlo.

Otra desventaja es que uno tiene que decirle a la clase mock, que valores espera. Las expectations. Ejemplo:


Lo que resulta un poco engorroso a veces si la función es compleja.

Como verán, soy bastante crítico de este tipo de soluciones. Mi principal problema es que agregan complejidad al código y más complejidad, es mayor probabilidad de errores. El test unitario tiene que ser lo más simple posible, tener la menor cantidad de errores. Y agregar mocks significa todo lo contrario.

Por supuesto, que se gana en velocidad. El tema es el siguiente: Constantemente estamos corriendo 300 test unitarios? Yo personalmente solo corro los tests unitarios de los métodos y clases que estoy tocando en este momento o calculo que pueden llegarse a verse afectados. En todo caso, al final del día, se corre todos los test para verificar que no se suba nada que rompa el código, pero tiene sentido hacerlo continuamente?

Y si no es así, entonces cuanto es la ganancia de velocidad?

También uno puede plantear soluciones intermedias. Probar las clases repository o DAO o aquellas clases de bajo nivel cuya función es trabajar con la base de datos sin mockeo y las clases de negocio, usando mock. De esta manera, al probar tanto contra la base de datos y contra una clase mock, estoy ganando fiabilidad en el test (al probar los repository directamente contra la BD) y por otro lado, también gano velocidad al evitar testear las clases de negocio contra la BD.

Muchos dicen por otra parte, que no hay que confundir un test de integración con un test unitario. El test de integración se prueba con la base de datos y el test unitario no. Es una práctica habitual escribir estos 2 tipos distintos de test para una misma función. Es una opción bastante prolija, pero el costo es la duplicación de código de testing.

De todas maneras, más allá de los gustos personales de cada uno, esta solución existe y puede ser altamente recomendable en determinadas situaciones puntuales.

Como ya deberíamos saber, cuando uno desarrolla, existen múltiples formas de hacer lo mismo indistintamente en el 80% de los casos. Pero siempre, existe ese 20% restante, donde determinada forma es claramente más conveniente que las otras.

noviembre 23, 2010

Could not load type System.ServiceModel.Activation.HttpModule

Filed under: .NET, Tips — grimpi @ 10:46 pm

VOLVEMOS!. Porque el pueblo nacional y popular lo necesitaba.

Despues de un buen tiempo, Grimpi IT entra nuevamente en accion. Y ando bastante inspirado para escribir, asique preparanse.

Hoy empezamos por un error bobo que llevo bastante tiempo decular.
Que hacer cuando estamos corriendo un proyecto en .NET 4.0 y nos tira el siguiente error:
“Could not load type System.ServiceModel.Activation.HttpModule?

Esto suele pasar generalmente cuando se instala primero .NET 4.0 y luego se activa el modulo IIS HTTP Activate.
La solucion a este problema es simple: correr desde la linea de comandos la sentencia aspnet_regiis.exe -iru.

noviembre 22, 2008

Patrones de Acceso a Datos: Active Record

Filed under: .NET, Arquitectura, Capa de Datos, Patrones — Etiquetas: , — grimpi @ 10:12 pm

Existen varias estrategias, arquitecturas y patrones de diseño para el manejo de la lógica de negocio y el acceso a la base de datos.
Que determina el uso de una u otra arquitectura esta dado por la especificadores y características del software a desarrollar y también por el gusto de quien diseña el esqueleto de la aplicación (la subjetividad es un factor muy determinante en el desarrollo de software, muchas veces más que cualquier argumento racional).
Hoy vamos a ver uno de estos patrones: Active Record.
ActiveRecord es un patrón en el cual, el objeto contiene los datos que representan a un renglón (o registro) de nuestra tabla o vista, además de encapsular la lógica necesaria para acceder a la base de datos. De esta forma el acceso a datos se presenta de manera uniforma a través de la aplicación.
Lógica de Negocio + Acceso a Datos en una misma clase.
Una clase Active Record consiste en el conjunto de propiedades que representa las columnas de la tabla más los típicos métodos de acceso como las operaciones CRUD, búsqueda (Find), validaciones, y métodos de negocio.
Personalmente me gusta mucho este enfoque, es muy elegante y simple.

En que situaciones CONVIENE usar este patrón?

  • Lógica de negocio simple y poco relacionada con otras entidades.
  • Es ideal cuando la estructura de la tabla coincide con la estructura de la clase.

En que situaciones NO CONVIENE de Active Record:

  • Es simple. Esto es bueno y malo al mismo tiempo. Con lógica de negocio compleja, este patrón pierde coherencia.
  • Otra desventaja que al estar tan acoplado a la estructura de la clase, un cambio en el diseño de la tabla, implica cambiar la clase.
  • En situaciones de operaciones de alto volumen de datos, el overhead que se paga en el pasaje y carga de datos, es innecesario. Esta desventaja aplica tanto a Active Record, como a cualquier otro diseño orientado a objetos.
  • Muchos “puristas” de OOP critican que ActiveRecord tiene una misma clase tanto la responsabilidad de acceder a la base como de manejar la lógica de negocio y “ensucia” el código. Nunca coincidí con ese fundamentalismo que a veces prioriza el purismo por sobre la simplicidad, pero es algo que muchos critican de este patrón.

Ejemplo de una clase típica de Active Record:

public class Order
{

public Order()
{
}

public Order(int orderID)
{
}

public int OrderID {get; set;}
public DateTime OrderDate {get; set;}
public DateTime ShipDate {get; set;}
public string ShipName {get; set;}
public string ShipAddress {get; set;}
public string ShipCity {get; set;}
public string ShipCountry {get; set;}

public void Insert()
{
// Inserta un registro en la tabla
}

public void Delete()
{
// Elimina el registro de la tabla
}

public void Update()
{
// Modifica el registro en la tabla
}

public static int GetCount()
{
// Retorna el total de registros de la tabla
}

public static Order FindById(int id)
{
//Busca en la tabla el objeto usando como criterio su id.
}

public static List<Order> LoadAll()
{
// Carga todos los regisotros de la tabla.
}

}
Por lo general siempre existen algunos métodos estáticos, como por ejemplo LoadAll(), que devuelve una colección de objetos de la misma clase. Otro típico ejemplo de un método estático es el FindById()

Conversión de datos

Este es un problema habitual en cualquier metodología que haga un mapeo de datos de un objeto con la base de datos.
Por ejemplo, si tenemos en la tabla una columna de tipo int cuyo valor en un registro es nulo, como convertimos este valor dentro de una propiedad del objeto? Por un lado podemos usar Nullable<int> que viene a partir de .NET 2.0. Otra estrategia es transformar valores nulos en 0. Puede parecer un poco desprolija esta metodología, pero muchas veces hay que preguntarse si queremos identificar entre un campo numérico nulo y uno cuyo valor sea 0. Obviamente, si queremos poder distinguir entre estos 2 valores, deberemos usar Nullable<int>.

Foreign Key Mapping Pattern (FKM)

Supongamos con el ejemplo que vimos anteriormente, que la tabla Order, tiene una FK a la tabla Customer. Como se debe comportar una clase Active Record cuando la tabla con la que trabaja tiene una Foreing Key?
Existen 2 maneras:

En primer lugar, mantener lo mas purista y simple posible y agregar solamente una propiedad más que sea el CustomerId, de manera que la estructura del objeto sea idéntica a la estructura de la tabla.

public int CustomerID {get; set;}

La segunda opción, es usar el patron Foreign Key Mapper. En mi opinión, una opcion mucho mas clara mucho más clara que consiste en vez de agregar una propiedad que represente el ID de la tabla, agregar una propiedad que sea una referencia directa al objeto.

public Customer Customer {get; set;}

Row Data Gateway Pattern (RDG)

Row Data Gateway es un patrón exclusivamente orientado al acceso a la base de datos, pero de características similares a Active Record.
La gran diferencia entre ambos, es que Active Record incluye métodos de acceso a la base de datos y métodos de lógica de negocio, mientras que Row Data Gateway, solo incluye métodos de acceso a la base.

Frameworks y generadores de codigo

  • Castle ActiveRecord: Por lejos, el framework más común que para trabajar con Active Record en .NET. Esta implementado sobre nhibernate, por lo cual también hay que tener esta librería para poder usarlo.
  • LINQ to SQL: Es la solución desarrollada por Microsoft para el mapeo de objetos con la base de datos. Puede también usarse con el patrón Active Record.
  • Además de estos frameworks, existen herramientas de generación de código en base a este patrón como .netTiers. También uno se puede crear su propio template de generación de código con MyGeneration o CodeSmith.


noviembre 12, 2008

Interop y cómo usar un componente .NET desde Visual Basic 6 y ASP

Filed under: .NET, Interop — Etiquetas: , , — grimpi @ 2:22 am

La tecnología COM fue la solución de Microsoft para el desarrollo de componentes reutilizables que puedan funcionar de manera distribuida y que sean independientemente del lenguaje de programación.
Con el desarrollo de .NET, COM quedo relegado. Sin embargo, muchos sistemas actualmente en producción, especialmente los desarrollados en VB 6 y ASP legacy, siguen usando esta tecnología.
Dado que existe una plataforma de desarrollo mucho más robusta y potente como .NET, es posible crear componentes en esta tecnología y que puedan ser invocados desde una aplicación VB 6 o ASP? La respuesta es afirmativa.
Dentro del Framework .NET, existe una librería llamada Interop que permite tanto usar un componente COM desde .NET como permitir llamar un assembly desde una aplicación COM.

Hoy vamos a explicar esto último, cómo usar un componente desarrollado en .NET desde ASP legacy o Visual Basic 6. La idea no es entrar en profundidad en este tema ni todas sus desventajas, sino hacer una guía rápida para el desarrollo de componentes COM en .NET.

  • El primer paso es crear explícitamente interface POR CADA clase que queremos exportar a COM. Si no lo hacemos, el compilador lo va a hacer solo, con el riesgo de perder compatibilidad binaria. Para decirle al compilador que no genera una interface por cada clase a exportable, hay que poner en el archivo assembly esta sentencia:

[assembly: ClassInterface(ClassInterfaceType.None)]

  • Hay que indicar como queremos que se instancien las clases COM (Late binding o Early bindin o ambos). Si queremos que se puedan crear de las 2 maneras, en cada interfaz hay que poner el atributo:

    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsDual)]

    Si solo queremos Late bindig hay que poner (recomendado)

    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsDispatch)]

  • Las clases que no se desean exportar a COM deben tener el atributo ComVisible(false)
  • Se debe firmar el componente, ya sea usando el programa sn.exe –k o directamente desde la IDE (esto solo se puede con VS 2005/2008).
  • Una vez compilado, se debe usar el programa Gacutil.exe para poner el assembly en la GAC (mas info sobre la GAC aca) y regasm.exe para generar y registrar el TLB del assembly.
    Ejemplo:

regasm Nombre.dll /tlb: Nombre.tlb

gacutil /i Nombre.dll

Para deregistrar el componente, hay que ingresar

regasm /u Nombre.dll /tlb: Nombre.tlb

gacutil /u Nombre.dll

Lamentablemente por alguna razón, el instalador de Visual Studio 2005/2008 no viene con el regasm.exe, por lo cual para conseguirlo es necesario descargar todo el SDK de .NET (http://www.microsoft.com/downloads/details.aspx?FamilyID=fe6f2099-b7b4-4f47-a244-c96d69c35dec&displaylang=en).

  • Una vez registrada el tlb, podemos usarlo desde VB 6 como si fuera un típico componente COM tradicional.

Consideraciones y Restricciones:

  1. Los constructores con parámetros no se pueden exportar a COM.
  2. Cuando se pasa un parametro variant en ASP o VB6 a un metodo de .NET se debe pasar entre parentesis. Sino genera el error Invalid Procedure or call Argument.
    Ejemplo:
    call ClaseInstancia.MetodoNuevo((ParametroVariant),OtroParametro)
  3. No se pueden usar NullTypes ni Generics.
  4. El paso de .NET a COM, requiere de una capa intermedia (marshaling), que por supuesto tiene un costo de procesamiento, algo que hay que tener en cuenta en sitios con alta cantidad de usuarios.
  5. Interop debe ser entendido y usado como una solución de corto y mediano plazo, para facilitar la migración de un sistema VB 6/ASP legacy a la plataforma .NET, no como una práctica recomendable.

mayo 3, 2008

Listar todos los ítems de un Enum vía reflection

Filed under: .NET, Reflection — grimpi @ 2:59 am

Post simple y práctico, como listar todos los ítems de un Enum vía reflection:

public static IEnumerable GetEnumList()
{
    Type enum = typeof(T);
    Array enums = Enum.GetValues(enum);
    List enumValList = new List(enums.Length);
    foreach (int val in enumValArray)
    {
        enumValList.Add((T)Enum.Parse(enum, val.ToString()));
    }
    return enumValList;
}

public static class Program
{
    public enum ObjectType
    {
        Item1 = 1,
        Item2 = 2,
        Item3 = 3
    }

    static void Main()
    {
        foreach (ObjectType state in GetEnumList())
        {
	    System.Console.Out.WriteLine(GetEnumDescription(state));
        }
    }
}

abril 9, 2008

El patrón DAO

Filed under: .NET, Arquitectura, Patrones, SQL Server — grimpi @ 1:12 am

Yo no soy un fanático de implementar montón de patrones y capas a los sistemas. Hoy en día hay sistemas que para desarrollar una función, requieren escribir en hasta 7 archivos diferentes.
Muchas veces complica más las cosas de lo necesario.
Sin embargo, uno de los patrones en mi opinión “fundamentales” del desarrollo de software, es el DAO (Data Access Object).
El DAO maneja la conexión con la fuente de datos para obtener y almacenar datos.

El uso de este patrón ofrece varios beneficios para la persistencia de datos:
* Sirve para separar el acceso a datos de la lógica de negocio. Algo altamente recomendable en sistemas medianos o grandes, o que manejen lógica de negocio compleja.
* Encapsula la fuente de datos. Esto es especialmente beneficioso en sistemas con acceso a múltiples entradas.
* Oculta la API con la que se accede a los datos. Por ejemplo en .NET si usamos siempre OleDb y queremos cambiar al NHibernate.
* Centraliza Todos los Accesos a Datos en un Capa Independiente

Cuando trabajamos con DAO, trabajamos en un mundo donde desconectado, donde nuestros datos se deben persistir en objetos.
Por lo tanto, cuando nos piden realizar una operación, se abre la conexión a la base, se ejecuta el comando, si es una operación de lectura, se vuelca el contenido hacia una estructura de datos y se cierra la conexión.

Transacciones:
Un problema muy común cuando se trabaja con este patrón, es como usar las transacciones.
Se deben ejecutar todas las operaciones dentro de un método?
Puede un DAO invocar métodos en otro DAO? Quien y como se deben manejar las transacciones?
Bueno, todo esta problemática que define el límite de la transacción se llama “Transaction demarcation”.
Existen 2 modelos diferentes que aplican según la necesidad de la operación transaccional que se va a efectuar.
Uno hace al objeto DAO responsable de la transacción, el otro desplaza la transacción al objeto que esta llamando el método DAO.
El primer caso (y el más usual) se puede codificar de la siguiente manera en C#:

public class ProductoDAO
{
public void Eliminar()
{
SqlConnection connection = new SqlConnection(“CONEXION”));
conn.open();
using (SqlTransaction trans = new SqlTransaction(conn))
{
SqlCommand com = new SqlCommand(“DELETE FROM P1”, conn, trans);
com.Execute();
SqlCommand com2 = new SqlCommand(“DELETE FROM P2”, conn, trans);
com2.Execute();
SqlCommand com3 = new SqlCommand(“DELETE FROM P3”, conn, trans);
com3.Execute();
trans.Commit();
}

conn.close();
}

}

En este ejemplo, para eliminar todos los productos y tablas relacionadas, se llama al objeto que maneja las transacciones de ADO.NET.
Con lo cual es perfectamente lógico encapsular el borrado de todas las tablas en un mismo método DAO, ya que se está afectando solamente la entidad Producto.

Pero supongamos que queremos eliminar transaccionalmente además de todos los productos, todas las ventas y todas las agencias.
Seria correcto meter la lógica del borrado de Ventas y Agencias dentro del método EliminarProducto? Como funcionar, funcionaria obviamente, pero estaríamos mezclando operaciones de distintas entidades y peor aún, estaríamos agregando métodos poco reutilizables y confusos.
Entonces lo correcto en este caso sería meter la lógica de la transacción fuera del DAO.
Para poder implementar esto, es necesario usar Transacciones distribuidas que .NET se implementan con EnterpriseService (En Java existe JTA). En caso de que usemos SQL Server 2005, podemos simplificar su considerablemente.

public class Negocio

{
public static void EliminarTodo
{
using (TransactionScope scope = new TransactionScope())
{
VentasDAO.Eliminar();
AgenciasDAO.Eliminar();
ProductoDAO.Eliminar();
scope.Complete();
}
}
}

Pasaje entre capas:
Ahora bien, ya sabemos porque debemos usar DAO y que beneficios nos trae.
Pero como deben ser el pasaje de datos con esta capa? Qué tipo de estructura usar?
En .NET existen varias variantes:

1) Dataset (tipado o no tipado)
2) XML
3) Data Transfer Objects (o objetos de Entidad)

Dependiendo de las particularidades de la aplicación, una opción puede ser mejor que la otra.
Definitivamente en la mayoría de los casos, usar Dataset no es la mejor práctica. Estamos de acuerdo que tal vez sea la opción más “cómoda”, pero los dataset son objetos pesados y lentos (en comparación con un Datareader), tienen montón de información, propiedades y métodos que no necesitamos.
Pero lo peor no es eso, la principal desventaja es que fuerza a toda la aplicación a usar un objeto de una tecnología especifica.

La más común de todas, es usar los Data Transfer Objects (DTO), también conocido como Value Object (VO). Es el típico patrón asociado a DAO.
Que son los DTO? Bueno, no son más que simples objetos que solo tienen getters y setters, que sirven para transportar la información de una capa a otra. El usar este patrón, ganamos performance, ya que al ser objetos livianos ocupan menos memoria, además de que nos permite abstraernos de cualquier tecnología especifica.

Recomendaciones a la hora de implementar DAO:

1) Combinar con el patrón singleton:
Tiene sentido tener múltiples instancias de DAO en memoria?
En la mayoría de los casos no, por eso yo por lo menos, suelo declarar todas mis clases DAO como static.

2) Crear una interfaz y un factory:
Todos los DAO generalmente tienen métodos comunes a todos, como DeleteById, GetById, GetAll, etc.
Declarar una interfaz IDAO, nos permitiría hacer un factory de DAOs.

3) Evitar el uso de dataset:
Si, como dije antes, es cómodo usarlos, nos ahorran tiempo de desarrollo. Pero a un costo alto.

Links:
http://www.ibm.com/developerworks/java/library/j-dao/
http://www.miguelmatas.es/blog/2007/11/13/mejorando-nuestro-dao-y-dto/
http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.htm

marzo 3, 2008

Add-In Property Generator para Visual Studio

Filed under: .NET, Add-In ProperyGenerator — grimpi @ 2:46 am

En mis épocas de programador en Java, usaba el Eclipse. Este excelente IDE, tenía una opción de refactoring que se usa para generar todos los getters y setters de una clase a partir de las variables privadas declaradas en la misma. Lo que en Java se llama getters/setters, en C# o VB sería el equivalente a las propiedades de una clase.

Siempre extrañé esa funcionalidad en Visual Studio. Cuando tenemos clases de 15 o más propiedades, tomarse el trabajo de generar 1 x 1, es aburrido.

Por lo tanto señores, he decidido hacerme mi propio Add-in de refactoring para agregarle esta interesante opción al Visual Studio. Este Add-in que desarrollé es compatible tanto con el Visual Studio 2005 como 2008. He visto un viejo Add-in, que se llama VsPropertyGenerator, que hace más o menos lo mismo, pero no tiene soporte y a mí no me funcionó y además, el que desarrolle yo, considero que es más fácil de usar.

Es libre, gratuito, pueden copiarlo, piratearlo y más que nada, disfrutarlo. El link para bajarlo es el siguiente:

http://www.opendbdiff.com/Addins.rar

Las opciones para instarlo se encuentran dentro de un archivo .txt. Cualquier sugerencia, problema o duda, dejen un comentario aquí, que prometo contestar.

Older Posts »

Blog de WordPress.com.