Como rescatar de las llamas del infierno un MDF sin el LDF

agosto 11, 2009 07:27 by sergio

Tomando como referencia el tipo de redacción de mi colega DDAZ voy a escribir este POST haciendo alusión a un “posible” caso de la vida real. Quiero aclarar que no soy DBA y no soy una eminencia optimizando sentencias SQL o una cosa por el estilo. Los nombres utilizados y su parecido con la realidad son mera coincidencia. 

El DBA despistado 

Josué, el encargado de la integridad de la información  y de los aspectos ambientales de la información de de una prestigiada empresa prestadora de servicios de tecnología (DBA), consiente y preocupado ante cualquier proceso de recuperación de desastres, análisis de rendimiento y optimización de base datos, olvidó (“por error”). Programar ya sea incrementalmente, diferencialmente o totalmente respaldos propios de la información contenida en las bases de datos de la compañía. 

Un día (viernes, que raro), ocurrió algo que estaba contenido en el plan de recuperación a desastres y solo se pensaba que podría llegar a ocurrir si el experimento que se está realizando en Suiza (entre las montañas del Jura y el lago de Ginebra), generara un poderoso arranque de gravedad que comprimiera la materia y terminara con la vida tal cual la conocemos. Un simple apagón de energía eléctrica, lo cual ocasionó que se dañaran varios sectores en disco duro, se malogrará el sistema de arranque del sistema operativo y se perdieran los log de transacciones de todas las bases de datos (LDF).

Cabe mencionar que el SMBD era SQL Server. La empresa sufrió mucho operativamente y la información vital de la misma, jamás se pudo recuperar. JAMÁS!! 

¿Por qué Sucedió esto? 

Josué, como todo profesionista promedio, tuvo un escenario en donde la teoría no sirve para nada ante situaciones prácticas donde se requiere actuar rápido para mantener el negocio. Adicionalmente también desconocía las bondades y la importancia de realizar respaldos de sus bases de datos como lo detalla la siguiente tabla*: 

 

Respaldo

Archivos en Respaldo Ventajas Desventajas
Completo ("Full") Todos Con este respaldo únicamente es posible recuperar toda la información Tiempo de Ejecución
De Incremento ("Incremental") Archivos con archive bit activo.(Aquellos que hayan cambiado desde el último Respaldo Completo) Velocidad Requiere del último Respaldo Completo y de todos los Respaldos de Incremento que le siguieron para recuperar el Sistema
Diferencial ("Differential") Archivos con archive bit activo.(Aquellos que hayan cambiado desde el último Respaldo Completo) Sólo requiere del último Respaldo Completo y del último respaldo Diferencial Ocupa mayor espacio en discos comparado con Respaldos de Incremento

*Clasificación de Respaldos. Osmosis Latina - http://www.osmosislatina.com/soporte/respaldos.htm 

¿Qué hacer si ya valió? 

Cabe mencionar que la siguiente alternativa solo funciona para SQL Server y no es una opción muy “elegante” al problema, yo sigo la siguiente filosofía: “A problemas piñatas, soluciones piñatas”, no por algo tengo un diploma a las “marranadas” (hablando de soluciones tecnológicas). 

La solución propuesta sería: 

1.    Crear las bases de datos afectadas en blanco, detener el servicio de SQL Server y cambiar el MDF por el que rescataron del server caído (Q.E.P.D). 

2.    Eliminar el LDF que se generó en blanco y reiniciar el servicio de SQL. Dado esto debería marcar la base de datos como suspect. 

3.    Posicionarse en la base de datos MASTER (USE MASTER) 

4.    Cambiar las opciones de configuración global del servidor actual para que permita hacer cambios al mismo. 

EXEC sp_Configure 'ALLOW UPDATES', 1
RECONFIGURE WITH OVERRIDE 

5.    Cambiar el estado de la base de datos a MODO DE EMERGENCIA. 

UPDATE SYSDATABASES SET STATUS = 32768 WHERE NAME = 'NombreBaseDeDatos'  

6.    Cambiar las opciones de configuración global del servidor actual para que ya no permita hacer cambios al mismo

EXEC sp_Configure 'ALLOW UPDATES', 0
RECONFIGURE WITH OVERRIDE 

7.    Cambiar la base de datos afectada a opción de usuario simple. 

EXEC sp_DBOption 'ArchivoIntegracion', 'SINGLE USER', 'TRUE' 

8.    Reconstruir el LOG de transacciones (LDF) de la base de datos (MDF). 

DBCC REBUILD_LOG ('NombreBaseDeDatos', 'C:\Program Files\Microsoft SQL Server\MSSQL\Data\NombreBaseDeDatos_Log.ldf') 

9.    Cambiar las opciones de configuración global del servidor actual para que permita hacer cambios al mismo. 

EXEC sp_Configure 'ALLOW UPDATES', 1
RECONFIGURE WITH OVERRIDE 

10. Cambiar el estado de la base de datos a MODO NORMAL. 

UPDATE SYSDATABASES SET STATUS = 0 WHERE NAME = 'NombreBaseDeDatos' 

11. Cambiar las opciones de configuración global del servidor actual para que ya no permita hacer cambios al mismo 

EXEC sp_Configure 'ALLOW UPDATES', 0
RECONFIGURE WITH OVERRIDE 

12. Cambiar la base de datos afectada a opción de usuarios múltiples. 

EXEC sp_dboption 'ArchivoIntegracion', 'SINGLE USER', 'FALSE' 


Y voila, ya quedó milagrosamente rescatado nuestro MDF sin necesidad de contar con el LDF respectivo. Josué ya puede estar más tranquilo al respecto y tener más cuidado para la próxima vez que ocurra esto en su organización (que esperemos y jamás vuelva a suceder).


Actualmente calificado con 5.0 por 3 personas

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

VSTO Capitulo 1 - Aplicaciones con Office? y eso como se come?

agosto 6, 2009 01:07 by ddaz

Les cuento 2 historias…., de esas que casi nunca ocurren –mínimo unas 500 veces al día en todo el mundo -  en un lugar muy muy lejano – quizá a 5 metros de Uds.-, cualquier parecido con la realidad, es pura coincidencia!!.

1 - El y  Su Amado Excel:

Era una persona, común y silvestre, que había estudiado alguna carrera de administración o0049648001181143847-shin-chan-enfadado quizá contabilidad o derecho, pudiera ser hasta “secretariado computarizado bilingüe” – y en mas extraño de los casos puede ser medico-, el punto es  que sus bastos conocimientos de computación –o informática- se extendían a un curso de “computación u Ofimática” de unos 6 meses – o quizá un poco mas-, sabe manejar a la perfección el Word, Excel, Outlook y el PowerPoint es súper especialista usando el MSN y sabe aplicarle parches para usar varias cuentas de Messenger a la vez, sin contar sus amplios conocimientos en Hi5, MetroFlog, FaceBook; esta persona como tal, siente que ya sabe lo suficiente y no le interesa saber mas de “computación”, ya que sabe que si tiene algún problema, existen unos seres extraños al que llama nerds, y que por mas que entre ellos se llamen “geeks”, para el son “nerds mejor vestidos”. se siente satisfecho con lo que sabe, y quizá lo único que le interesa saber es de donde bajar mas iconos para el Messenger.

Esta persona común y silvestre –si, de esas que andan sueltas por allí-, “implemento” u “organizo” su área, metiendo sus conocimientos de “informática" -a su modo-,  lo que antes se manejaba en papel, el lo movió a “archivos de Word y/o Excel”, hizo sus plantillas, toda la información que ocupaba “organizada”, la tiene en múltiples archivos de Excel “muy ordenadamente, separados por semana o mes” , cuando tiene que escribir un reporte, sabe que tiene una hoja base en Word, y solo hace “copy and paste” , y agrega una nueva hoja a su archivo de Word o modifica el existente; si algún día su jefe ocupa un reporte en graficas de los datos que maneja, puede crear una grafica en Excel o importarla a Word, o si ocupa unos nuevos cálculos, los puede hacer en unos 15 minutos usando las formulas de Excel. En otras palabras, el trabajo que realiza, a su forma de ver, esta organizado y tiene todo lo que ocupa, por mas que su jefe diga que el es ineficiente, el siente que tiene todo controlado, con sus macros y formulas, con sus hojas de Word, esta cómodo, ya que siente que no ocupa saber mas de las computadoras – solamente ocupa saber como ganar al maldito solitario y/o buscaminas, que siempre lo vence-,  es una persona que contantemente se actualiza en su profesión – la que sea-, va a cursos de actualización, y para no perder el ritmo fue a otro curso de ofimática, donde le enseñaron a usar la ultima versión del office.

Un día, llego lo llamo su jefe y le dijo que iban a “mejorar” su área, que habían contratado a una consultora que les haría un sistema, que mejoraría el proceso de la empresa y este conseguiría que se logre  ahorrar tiempos en el trabajo y tendrían un mayor control, de todo lo que pasa en la empresa, mientras su jefe decía todo esto, esta persona común y silvestre solo pensaba “pero yo tengo todo controlado, se que archivo de Excel tiene que información, se generar mis reportes, se hacer los cálculos, seguro andan pensando en reemplazarme por una maquina como esos robots de la TV, y me quedare sin trabajo” –aunque suena ilógico, hay quienes de verdad terminan pensando así-, y le presentan a ese ser extraño que “ mejorara los procesos y automatizara su trabajo”…

este ser extraño le hace muchas preguntas, lo interroga de todo  y el le cuenta aunque por dentro sigue pensando que será reemplazado por algún robot, y como se siente en “peligro” , siente que no debe decirle todo  o quizá simplemente de la pura presión, se le olvida hacerlo..; esa consultora cuenta un un “especialista en usabilidad y diseño  de interfaz”, que iba a hacer que sea “fácil de usar”.

y llega el día en que le enseñan el “nuevo sistema”, se le hace algo extraño, e totalmente diferente a su tan amado office, le parece un rectángulo con muchos botoncitos e iconos, allí no sabe donde están las cosas, por mas que le dan un curso de capacitación, se le hace complejo, además que si hacer algunos cálculos, no puede hacer sumas en las celdas de al lado “ por que no hay!”, y si ocupa nuevas cosas tiene que hacer un pedido, luego esperar unos días o semanas, ademas de que tiene algunos problemas que los seres raros llaman “bugs”, para el todo esto es muy pesado, el extraña su amado Excel y Word, donde si tenia un error de calculo, solo modificaba  y listo; y entonces llego un día, había una reunión y en esa el jefe le pidió de “ya” un reporte especial –con sus graficas y todo, ya que los jefes solo saben leer graficas- y “oh sorpresa” el reporte no existía en ese famoso sistema, llamo a los seres raros y ellos le dijeron que en unos 5 días estaría el reporte, luego de algunas discusiones, le dijeron que para el día siguiente, pero el los ocupaba de ya, así que agarro algunos datos de otro reporte, abrió su tan amado Excel copio los datos que ocupaba, y genero su grafica, todo esto en una 1 hora – mucho menos que lo que tardan los seres raros-, y de alli se colgó para comenzar a bombardear a ese sistema…, luego de un tiempo, el sistema dejo de ser usado, y el Volvió a su amado Excel.

2 - Amor al Word por toda la vida!

Otro Caso es de un Medico, que hacia los reportes de las consultas de su consultorio en "en Word”, tenia muchos muchos archivos, y un día fueron a ofrecerle un sistema, le costo una buena cantidad –le cobraron bien, pq es doctor y dicen k puede pagar- el lo pago, pensando que le ayudaría, e igual recibió un cuadrado, que no se parecía en nada a su Word, con muchos rectángulos donde le dijeron que metiera los datos, y donde tenia que escribir el diagnostico, no veía forma de resaltar los aspectos importantes, – negritas, subrayado, etc- luego de un tiempo, los seres extraños, hicieron unos botones para que pueda hacer eso, pero no era tan cómodo y simple como su amado Word, que por mas que le decía que tenia una copia pirata, aun le dejaba hacer las cosas como el quería, luego de un tiempo…. dejo el sistema y volvió a su tan amado Word..

Por que Sucedió esto?

así como estos casos hay miles y miles, de proyectos que terminaron en fracaso, y ojo, no me refiero necesariamente a los proyectos que están súper mal programados.. – eso es otro tema –, en muchos casos, es por que los usuarios son personas que no les interesa estar actualizados “tecnológicamente”, no saben, ni les interesa saber que existen cosas como silverligth, Ajax, WPF, etc. personas que tienen carreras no relacionadas con cosas de tecnología, mas que con cosas de ofimática, personas que están mas preocupados en actualizarse en cosas relacionadas con su carrera, que en cuestiones tecnológicas, están cómodos con su forma de trabajar con el Office y tienen gran resistencia al cambio, muchas veces son los causantes de “serruchar, grillar, o promover que un sistema deje de ser usado”  ya que comienzan a ver todos sus “problemas”, los cuales básicamente son “por que el office me hace esto y el sistema no?” , aunque parezca ilógico, hay sistema que fracasan por eso, por que esos usuarios comunes y silvestres, no se acostumbran a esa nueva interfaz, ya sea web, win , RIA, etc… por que simplemente no se acostumbran – y no le da la gana de acostumbrarse –, en  teoría lo usuarios deberían usar si o si el sistema, pero la realidad muestra que muchas veces, estos son saboteados por los mismos usuarios, o hacen a propósito el trabajo mas lento… y esto por que? 

ellos solo quieren usar el office y nada mas, para nuestra suerte desde hace un tiempo existe algo llamado

Visual Studio Tools for Office – VSTO

y que 3#$#$%#$%#  es eso? 

Son herramientas, que están en el Visual Studio –desde el VS 2005 con modo gráfico, ya que en 2003 era como un beta, muy limitado –, las cuales nos dejan desarrollar aplicaciones para office, y OJO, no me refiero a VBA, esto es totalmente diferente, ya que se pueden usar los lenguaje VB o C#, la programación es muy parecida a Windows Form, con la diferencia que en el ide del Vs en vez de ver un formulario, veremos una hoja de Excel, o de Word, –además de poder hacer add-in muy fácilmente-, pero que beneficios tenemos aparte de esto? :

  • Podemos aprovechar la funcionalidad existente del Office:  cuestiones como guardado, importación, exportación, graficas, corrector ortográfico, ya están incluidos, listo para usar por el cliente, sin que nosotros tendríamos que programar algo extra, aunque como es lógico,  mediante programación podemos usar y extender esas funcionalidades, esto nos ahorra mucho tiempo de programación ,de cosas repetitivas.
  • Interfaz Amigable para el usuario : Muchas veces la resistencia al cambio, del usuario es por que no se siente seguro con la aplicación, pero si le damos una aplicación que este dentro del office, de entrada el usuario se sentirá mas cómodo de usarlo, ya que sabe donde se encuentra mucha funcionalidad, y solo hay que indicarle que mas se le a agregado; con esto, la resistencia al cambio es mínimo o nulo.
  • El Usuario puede hacer Cambios sin ocupar llamar a soporte constantemente : ya que las demás celdas o funcionalidad, no quedan bloqueadas – por defecto-, si el usuario por ejemplo ocupara hacer un grafico X de los datos que le muestra el sistema, no ocuparía llamar a soporte, solo lo haría como ya sabe hacerlo, o igual si ocupa modificar un reporte – una suma, un calculo extra-, el usuario podría agregar los campos que ocupe, ya que sabe usar el Excel como tal sin ningún problema.
  • soporte para trabajar “Offline” – en casa – :  como el office ya de por si puede guardar datos, podemos configurar la aplicación, para poder trabajar datos, en modo offline – trabajo en casa les suena?- y ya cuando vuelve a la oficina, la aplicación  actualizaría la db y esto sin necesidad de instalar alguna db “imagen” en el cliente.
  • Soporta Lenguajes .NET : al estar dentro de .net, podemos usar los lenguajes de programación .net que usamos comúnmente, así que no habría que saber otro lenguaje de programación, lógicamente si cosas inherentes al VSTO – como trabaja- pero nos ahorramos el lenguaje.

los que mencione son algunas de las funciones, y las que a mi parecer son las mas destacables.

ahora si les cuento, hace unas 2 semanas, platicaba con un amigo y me dijo que por que no publicaba los borradores que tenia – post-  y bueno, digamos que me convenció, y los iré sacando, -en el orden de la cola en que están – , y  de los mas antiguos que tenia eran sobre VSTO,  así que sacare  varios POST, sobre como es el desarrollo para office,  el cual uso en mi trabajo y los usuarios que lo usan están muy satisfechos, intentare compartirles mis experiencias y tips de como programar allí, desde un “hola mundo” hasta aplicaciones mas avanzadas, y luego –quizá- si hay gente que le interese, hasta podría hacer un – o varios – webcast al respecto, lógicamente dependiendo del interés de la gente, según cálculos, enviare mínimo 1 por semana.. y si se me olvida, plz hágamelo recordar plz.

creo que sin querer me salió otro testamento – será posible que alguna vez envíe uno corto?? –, este fue la introducción, en el siguiente voy a mostrar ya de un modo técnico como trabaja el VSTO.

casi me olvido, lógicamente todo esto será con Visual Basic !

Salu2

Ddaz


Actualmente calificado con 5.0 por 1 personas

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Soluciones REALES a problemas REALES - ¿Quién dijo que no se puede transformar con XSLT 2.0 dentro de nuestras aplicaciones .NET?

mayo 4, 2009 06:54 by sergio

XSLT 2.0 es un interesante paso adelante en la tecnología de transformación XML, con ella, es posible crear productos de software que produzcan contenidos para diferentes dispositivos y plataformas. Con XSLT 2.0 y XPath 2.0, podemos realizar transformaciones de una forma mucho más sencilla y rauda haciendo uso de los XSLT Extension Objects.

 

Dicha la teoría (la cual a la hora de la hora no sirve para nada), me he topado con la necesidad en diversas ocasiones de hacer uso de las bondades antes mencionadas (entre otras que mencionaremos más adelante), lamentablemente con mis herramientas de desarrollo actual (VS.NET 2003, VS 2005 y VS 2008) no he podido echar mi imaginación a volar (Si estoy equivocado y si lo trae por favor corríjanme, yo en lo personal nunca he podido hacer XSLT 2.0), y es que ante problemas “piñatas” siempre son necesarias soluciones “piñatas” que requieren opciones que se salen un poquito fuera de lo ordinario. Espero en las próxima versiones de estas herramientas (VS 2010), venga ya considerado este estándar (desconozco si en el CTP hasta el día del POST esté ya considerado).

 

De cualquier forma, hay una opción de nuestros amigos de Altova (http://www.altova.com/altovaxml.html) llamada AltovaXML, muy versátil para realizar este tipo de transformaciones, ya que es un poderoso:

  • Motor de validación XML
  • Motor XSLT 1.0
  • Motor XSLT 2.0
  • Motor XQuery 1.0
  • Motor de validación XBRL

Con los cuales podemos realizar todo tipo de operaciones soportadas por el estándar W3C (para aplicaciones COM, Java y .NET), con todo el vigor de Altova, ah, y también: ¡GRATIS!  

Pero bueno, ¿Cómo diantres lo usamos?, muy sencillo, solamente hay descargar la herramienta de: http://www.altova.com/altovaxml.html, isntalarla y agregar dentro de nuestro proyecto la referencia al assembly Altova.AltovaXML.dll (C:\Archivos de programa\Microsoft.NET\Primary Interop Assemblies\Altova.AltovaXML.dll por default). Si nos marca cosas extrañas, hay que procurar registrar el componente (AltovaXML_COM.exe /regserver)

 

Ya una vez realizado esto, creamos nuestra transformación XLST 2.0:

 

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:barreteros_funct="http://www.barreteros.net">            <xsl:output method="text" version="1.0" encoding="UTF-8" indent="yes"/>            <xsl:template name="example" match="/">                        <xsl:value-of select="barreteros_funct:index-of-string('Sergio', 'gio')"/>            </xsl:template>            <xsl:function name="barreteros_funct:index-of-string">                        <xsl:param name="arg"/>                        <xsl:param name="substring"/>                        <xsl:sequence select="   if (contains($arg, $substring))  then (string-length(substring-before($arg, $substring))+1,        for $other in           barreteros_funct:index-of-string(substring-after($arg, $substring),                               $substring)        return          $other +          string-length(substring-before($arg, $substring)) +          string-length($substring))  else () "/>            </xsl:function>

</xsl:stylesheet>

Aquí estamos creando una función (y recursiva apa!) llamada barreteros_funct:index-of-string, la cual no da el index-of de una cadena contenida en otra, recibe dos parámetros como podemos ver: arg, que es la cadena original y substring que es la cadena que deseamos saber el index).  

Esta función, se manda llamar directamente desde el atributo select desde cualquier función xsl, como si se tratase de una función propia del estándar:  

<xsl:value-of select="barreteros_funct:index-of-string('Sergio', 'gio')"/> 

Esta nos arrojará como resultado un 4: 'Sergio', obvio. 

OJO: Si esta transformación la abrimos desde nuestro IDE de desarrollo comentado anteriormente, nos va a pintar un… grandioso mensaje de error a nivel <xsl:function subrayando la palabra de color azul (como si fuera una falta horrografía en Word). Pero no os preocupéis, si este error les causa problemas, cierren el archivo, así ya no lo verán. Ahora procederemos a realizar la transformación mediante AltovaXML: 

Protected Sub TransformarAltova(ByVal xslPath As String, ByVal strXML As String, ByVal TransformPath As String)

        Dim xslt2 As Altova.AltovaXML.IXSLT2 = New Altova.AltovaXML.Application().XSLT2()        xslt2.InputXMLFromText = strXML        xslt2.XSLFileName = xslPath        xslt2.Execute(TransformPath)    End Sub     Protected Function TransformarAltova(ByVal xslPath As String, ByVal strXML As String) As String        Dim xslt2 As Altova.AltovaXML.IXSLT2 = New Altova.AltovaXML.Application().XSLT2()        xslt2.InputXMLFromText = strXML        xslt2.XSLFileName = xslPath        Return xslt2.ExecuteAndGetResultAsString    End Function
 

 

Aquí hay dos funciones polimórficas, la primera realiza la transformación en una ruta determinada (TransformPath), la segunda regresa el resultado de la transformación en un arreglo de caracteres (As String). Simplemente se instancia el XSLT2 parser y llamamos el método Execute o ExecuteAndGetResultAsString según el escenario deseado.

 

De esta forma estamos solventando el problema REAL.

 

OJO: dada nuestra transformación mediante AltovaXML, necesitamos liberar el COM object de Altova:

System.Runtime.InteropServices.Marshal.ReleaseComObject(XSLT2) 

Si no realizamos esto, el proceso de Altova se queda corriendo dentro de los proceso de la maquina ejecutante y no se apaga o finaliza hasta que no se cierra la aplicación que lo manda ejecutar.

 

En nuestra próxima entrega veremos: ¿QUÉ TAN CHONCHO PUEDE SER UN XML PARA QUE LO PROCESE LINQ SIN PROBLEMAS?


Sea el primero en calificar este post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Soluciones REALES a problemas REALES - Request y Response Encriptados

marzo 28, 2009 14:30 by sergio

Quiero aprovechar para enviar un saludo a todos los miembros de la comunidad y para pedir una disculpa por esta ausencia tan larga que he tenido, por cuestiones laborales me ha sido complicado atender y compartir un poco de conocimiento.

En base a esto, he decidido comenzar a publicar soluciones REALES a problemas REALES con los que nos enfrentamos todos los días, ya estoy cansado de vagar por infinidad de sitios en donde no se dan SOLUCIONES a problemas cotidianos y en ocasiones PUERILES, pero que el desconocimiento de los mismos nos lleva a dolores de cabeza cuando los ambientes son PRODUCTIVOS con grandes volúmenes de transaccionalidad o cuando nos viciamos de dar una solución compleja a algo que no lo es. En este artículo vamos a ver un tema PUERIL, en el cual vamos a simular las clases del REQUEST y del RESPONSE, de tal forma que crearemos las nuestras y las mandemos llamar de forma tan natural que el uso es transparente pero encripta toda lo información contenida en el QueryString cuando la misma es muy sensible. 

1.     Primeramente vamos a crear un nuevo Sitio Web, en mi caso Visual Studio 2008, puede ser en cualquier versión del Framework, no estamos usando LINQ o alguna chuchería propia de la versión. 

2.     Vamos a crear 3 clases: MyRequest.cs, MyResponse.cs y MyEncriptor.cs, en esta ocasión voy a usar C#, no porque sea de los que están casados con algún lenguaje, sino que fue el primer lenguaje que me apareció en mi IDE cuando cree el proyecto. 

3.     Vamos a tirar código: 

MyResponse.cs 
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Text.RegularExpressions; /// <summary>/// Clase que simula el Response pero de una URL encriptada/// </summary>public class MyResponse{    public static void Redirect(String url, Boolean endResponse)    {        var pagina = string.Empty; var query = string.Empty;        try        {            pagina = url.Split('?')[0].ToString();            query = url.Split('?')[1].ToString();            query += string.Format("?{0}", url.Split('?')[2].ToString());        }        catch (Exception ex)        {            Console.WriteLine(ex);        }        finally        {            System.Web.HttpContext.Current.Response.Redirect(pagina + "?" + MyEncriptor.Encriptar(query), endResponse);        }    }

}

Explicación: Se está creando una clase MyResponse, la cual contiene otra clase estática llamada Redirect, la cual recibe de parámetro la URL de destino y una variable boolena que indica el termino de la ejecución de la página (como se hace en el response tradicional). Lo que hace esta función es dividir la parte de la URL en cuestión del QueryString de la misma, una vez obtenidos estos valores por separado se hace una encripción del QueryString y se le concatena nuevamente a la URL, dado esto se hace el Redirect tradicional. 

System.Web.HttpContext.Current.Response.Redirect(pagina + "?" + MyEncriptor.Encriptar(query), endResponse);  

MyRequest.cs 

using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Text.RegularExpressions; /// <summary>/// Clase que simula el Request pero de una URL encriptada/// </summary>public class MyRequest{    public class QueryString    {        public static String Get(String variable)        {            var res = string.Empty;            string Url = string.Empty;            try            {                Url = MyEncriptor.Desencriptar(System.Web.HttpUtility.UrlDecode(System.Web.HttpContext.Current.Request.Url.Query.Remove(0, 1)));                Regex r = new Regex(variable + "=(?<key>(.*?))(&|$)");                res = r.Match(Url).Result("${key}");            }            catch (Exception ex)            {                res = string.Empty;            }            return res;        }    }}

Explicación: Se está creando una clase MyRequest, la cual contiene otra clase estática llamada QueryString y la cual a su vez contiene una función estática llamada Get, esta recibe de parámetro una variable de tipo String y regresa de la misma forma el resultado de la obtención de un value determinado del QueryString. Lo interesante en esta clase es que obtenemos el QueryString actual (Ya encriptado), lo desencriptamos y mediante el uso de una expresión regular obtenemos la ocurrencia a sabiendas de cómo se forma un QueryString.                

Url = MyEncriptor.Desencriptar(System.Web.HttpUtility.UrlDecode(System.Web.HttpContext.Current.Request.Url.Query.Remove(0, 1)));                Regex r = new Regex(variable + "=(?<key>(.*?))(&|$)");                res = r.Match(Url).Result("${key}"); 

Esto como resultado nos arroja el valor esperado oculto dentro del chorizo de caracteres raros e ilegibles del QueryString. Este sencillo ejemplo es muy útil cuando necesitamos enviar información entre páginas y no queremos que el usuario malintencionado la cambie para fregarnos la existencia y ahorrarnos validaciones en código en caso de que alteren los parámetros dentro de la misma. 

Anexo un .ZIP (http://cid-a57150b9cc22cc3a.skydrive.live.com/self.aspx/Articles/RequestSiteExample.zip) con el código fuente utilizada. Si se están preguntando porque no pongo el código de la clase de encripción es porque la misma es irrelevante a la solución y puede ser cualquier tipo de algoritmo que creemos conveniente para realizar la misma. En este caso de ejemplo yo estoy utilizando una implementación del algoritmo DES tradicional. 


En nuestra próxima entrega veremos: ¿QUIEN FREGADOS DIJO QUE NO SE PUEDE TRANSFORMAR CON XSLT 2.0 DENTRO DE NUESTRAS APLICACIONES .NET?


Actualmente calificado con 5.0 por 1 personas

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Clases Abstractas vs Interfaces. ¿Cómo, Cuándo y Por Qué?

febrero 17, 2009 07:10 by sergio

Enviado por Johnatan Flores Carmona el 17 de febrero de 2009  

Saludos a todos, en esta nueva aportación quiero compartir con ustedes un tema que cuando se está iniciando en el aprendizaje de la programación orientada a objetos no se encuentra en ningún libro o bien, pocos instructores lo mencionan -debo admitir que cuando impartí la materia de Introducción a la Programación Orientada a Objetos en el Instituto Tecnológico de León ni siquiera lo mencioné- y me refiero a ¿Cuándo y por qué usar clases abstractas o interfaces?

El concepto de clases abstractas e interfaces puede ser un poco confuso para los principiantes en la programación orientada a objetos ya que una clase abstracta sin ninguna implementación se ve cómo una interface, sin embargo existen muchas diferencias y similitudes entre ellas.

¿Qué es una clase abstracta?

Una clase abstracta es una clase que no puede ser instanciada y que debe ser heredada. Una clase puede implementarse en su totalidad, pero lo más habitual es que se implemente parcialmente o no se implemente en absoluto, encapsulando funcionalidad común para clases heredadas. Para información más detallada, vea Clases abstractas.

¿Qué es una Interface?

Una interface describe un grupo de comportamientos relacionados que pueden pertenecer a cualquier clase o estructura. Las interfaces contienen las firmas de métodos, propiedades, eventos o indizadores. La implementación de los miembros se hace en la clase o la estructura que implementa la interfaz. Para información más detallada, vea Interfaces.

Diferencias y Similitudes

A continuación extraigo parte de una tabla del artículo Abstract Class versus Interface en la que se describen las diferencias y similitudes que existen entre las clases abstractas y las interfaces:

Característica

Interface

Clase abstracta

Herencia Múltiple

Una clase puede heredar tantas interfaces requiera.

Una clase sólo puede heredar una clase abstracta.

Implementación por defecto

Una interface no puede proporcionar ningún código de implementación, solo la firma.

Una clase abstracta puede proporcionar la implementación completa o parcial.

Modificadores de acceso

Una interface no puede tener modificadores de acceso, todas sus firmas son públicas.

Los miembros de una clase abstracta pueden tener modificadores de acceso.

Núcleo vs Periferia

Las interfaces son usadas para definir las habilidades periféricas de una clase. Un Humano y un Vehiculo pueden implementar una interface IMovible

Una clase abstracta define el núcleo de una clase y es usada para objetos del mismo tipo.

Campos y Constantes

No pueden ser definidas en una interface

Una clase abstracta puede contener campos y constantes.

Recomendaciones para el uso de clases abstractas vs interfaces

La opción de diseñar tu funcionalidad cómo una interface o cómo clase abstracta puede ser difícil en algunas ocasiones. Microsoft en su artículo Recommendations for Abstract Classes vs. Interfaces nos hace las siguientes recomendaciones que trataré de ejemplificar para mostrar las ventajas de seguirlas.

Múltiples Versiones

Si sabe de antemano que va a crear varias versiones del componente, cree una clase abstracta. Las clases abstractas proporcionan un medio fácil y sencillo para crear versiones de los componentes. Al actualiza la clase base, todas las clases heredadas se actualizan automáticamente con el cambio. Por el contrario, las interfaces no se pueden cambiar una vez creadas. Si necesita una nueva versión de una interfaz, deberá crear una totalmente nueva.

Ejemplo: Pensemos en el caso de crear el ABC de una base de datos que contiene la tabla Persona, y además dos especializaciones de esta llamadas Cliente y Empleado; también existe la regla de negocio que indica que no puede registrarse a una persona si no es registrada cómo cliente o cómo empleado.

Solución con Clases Abstractas: Se debería de crear una clase abstracta llamada Persona y que defina las propiedades comunes entre Empleado y Cliente así como los métodos que implementan los procesos de Alta, Baja, Cambio de la tabla Persona; adicional a esto se deben crear las clases Empleado y Cliente, ambas heredan de Persona. Cada una deberá definir las propiedades que los diferencian y sobrescribir los métodos Alta, Baja y Cambio de la clase padre, en la sobre escritura de los métodos, se tendrá que hacer una llamada al método base correspondiente y agregar la implementación para modificar la tabla correcta.

Solución con Interfaces: Se debería de crear una interface llamada IPersona y que defina las firmas de los procesos de Alta, Baja, Cambio; adicional a esto se deben crear las clases Empleado y Cliente, ambas que implementen la interface IPersona. Cada una deberá definir las propiedades y campos comunes tanto comunes como diferentes, ambas también deben codificar la implementación de los métodos Alta, Baja y Cambio que realizarán los procesos en la tabla Persona y en la tabla correspondiente.

Conclusión: Cómo se puede ver, utilizando clases abstractas se puede reutilizar mucho código al heredar los campos, propiedades y llamando a los métodos de la clase base; en cambio con interfaces tenemos que re-escribir los campos y propiedades comunes en todas las clases así cómo el código de los métodos.

Funcionalidad Común

Si la funcionalidad que está creando va a ser útil en una amplia gama de objetos diferentes, utilice una interfaz. Las clases abstractas deben utilizarse principalmente para objetos estrechamente relacionados, mientras que las interfaces son más adecuadas para proporcionar funcionalidad común a clases no relacionadas.   

Ejemplo: Se tiene el caso de querer implementar diferentes medios de transporte que existen y se han identificado el Autobus, Avión y Barco. ¿Cómo se implementaría con clases abstractas y cómo con interfaces?

Solución con Clases Abstractas: Se crearía una clase abstracta llamada Transporte que defina el método abstracto Transportar; Se crearán las clases Autobus, Avion y Barco, todas ellas heredarán de Transporte y deberán realizar la implementación del método abstracto.

Solución con Interfaces: Se debería de crear una interface llamada ITransporte que defina la firma del método Transportar; Se crearán las clases Autobus, Avion y Barco, todas ellas implementarán la interfaz ITransporte.

Conclusión: A simple vista se podría decir que ambas soluciones son iguales, ya que las dos le delegan la responsabilidad de implementar el método Transportar a las clases finales Autobus, Avion y Barco, pero la diferencia está en lo siguiente, ¡No existe herencia múltiple! Por lo tanto con la solución de clases abstractas estaremos desperdiciando una oportunidad de heredar de otra clase, pensemos en este caso, podríamos tener una clase padre llamada Avion y las clases hijas Avioneta, AvionComercial, etc., entonces hazte la siguiente pregunta ¿Avioneta y AvionComercial deberían heredar de Avion o de Transporte? En este caso claramente se ve que la mejor opción es utilizar interfaces.

Pequeña Funcionalidad

Si va a diseñar fragmentos pequeños y concisos de funcionalidad, utilice interfaces. Si va a diseñar unidades funcionales grandes, utilice una clase abstracta.

Conclusión: Esta recomendación va muy ligada a las dos anteriores, mientras más grande la funcionalidad es más recomendable la reutilización por lo que las clases abstractas son la mejor opción; con funcionalidad pequeña no es recomendable perder la oportunidad de heredar nuestra clase con una clase padre que tenga una funcionalidad grande para reutilizar sus propiedades y métodos por lo que la utilización de interfaces es nuestra mejor opción.

Funcionalidad común

Si desea proporcionar funcionalidad común e implementada en todas las implementaciones del componente, utilice una clase abstracta. Las clases abstractas permiten implementar parcialmente una clase, mientras que las interfaces no contienen ninguna implementación para ningún miembro.

Conclusión: Siempre que encuentres funcionalidad común entre dos o más clases, busca la manera de utilizar herencia para la reutilización de código (mientras menos escribas mejor).

Si deseas el código fuente utilizado para este discusión puedes descargarlo de:


Actualmente calificado con 4.2 por 5 personas

  • Currently 4,2/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

‘Aplicaciones Dinámicas’ con .NET Reflection y su Rendimiento

febrero 11, 2009 06:38 by Admin

Enviado por Johnatan Flores Carmona el 19 de enero de 2009 

Saludos a todos, antes que nada quisiera comentar que felicito a los propietarios de este grupo así cómo a los usuarios por esta nueva etapa ahora en 'Live'. He sido miembro de este grupo desde ya algunos años y aunque mi participación ha sido casí nula me gustaria pensar "Año Nuevo, Grupo Nuevo, Actitud Nueva" así que para empezar con la nueva actitud, me gustaría compartir con ustedes algo que he tenido que a prender por las malas: El maravillos mundo de .NET Reflection........

Problema:

Actualmente en la institución donde laboro me asignaron a un proyecto que consiste en construir un ‘Bridge’ para que la aplicación ‘X’ pudiera comunicarse con la aplicación ‘Y’. Uno de los muchos requerimientos que solicitaron fue: ‘Actualmente debes conectar ‘X’ con ‘Y’, pero este bridge debe servir posteriormente para comunicar a ‘W’ con ‘Z’, ‘Y’ con ‘W’, etc. por lo que debe ser una aplicación que su funcionalidad deba ser configurable desde base de datos. ¿Cuál fue la solución a estos requerimientos?  R:= .NET Reflection. 

Solución con Reflection:

Implementaciones: Cada uno de las aplicaciones (W, X, Y, Z) tiene sus propias ‘reglas’ de comunicación, por lo que para comunicar XàY se requiere una ‘implementación’ diferente que para comunicar a WàZ y otra totalmente diferente para YàW.

Interfaz de implementación: Todas las implementaciones deberán exponer un método llamado ‘Ejecutar’ el cuál servirá para llevar a cabo los procesos necesarios para cada una de las implementaciones.

Fabrica de implementaciones: Se requiere un método que nos permita obtener la implementación correcta en base a los parámetros de entrada (posiblemente un ID o un nombre).

Diccionario de implementaciones: Requerimos un diccionario que nos permitirá conocer el nombre de la clase que deseamos utilizar para realizar la implementación correcta (en nuestro caso una base de datos o un archivo xml).

Prueba: El método Main que realiza la prueba (hipotetica) de esta solución sería de la siguiente manera:

    class TestRendimientoReflection

    {

        static void Main(string[] args)

        {

            

            //Codigo para medir el tiempo de ejecucion

            EjecutarTest(totalIteraciones);

        }

        static void EjecutarTest(int totalIteraciones)

        {

            Random generadorIdentificadores = new Random();

            for (int i = 0; i < totalIteraciones; i++)

            {

                int idClase = generadorIdentificadores.Next(1, 11);

                IImplementacion clase = FabricaImplementacion.CrearImplementacion(idClase);

                Console.WriteLine(clase.Ejecutar());

            }

        }

    }

Solución sin Reflection:

Implementaciones: (Igual que con Reflection)

Interfaz de implementación: (Igual que con Reflection)

Prueba: El método Main que realiza la prueba de esta solución (hipotetica) sería de la siguiente manera:

    class TestRendimientoSinReflection

    {

        static void Main(string[] args)

        {

            

            //Codigo para medir el tiempo de ejecucion 

            EjecutarTest(totalIteraciones);

        }

        static void EjecutarTest(int totalIteraciones)

        {

            Random generadorIdentificadores = new Random();

            for (int i = 0; i < totalIteraciones; i++)

            {

                int idClase = generadorIdentificadores.Next(1, 11);

                IImplementacion clase = null;

                switch (idClase)

                {

                    case 1:

                        clase = new Implementacion01();

                        break;

                    case 2:

                        clase = new Implementacion02();

                        break;

                    //Todos los case necesarios

                    default:

                        clase = new Implementacion10();

                        break;

                }

                Console.WriteLine(clase.Ejecutar());

            }

        }

    }

Rendimiento:

Cuando se me cuestionó sobre si la utilización de Reflection afectaría el rendimiento que podría tener la aplicación tuve que investigar sobre dicho tema y encontré la siguiente referencia: .Net Reflection and Performance

En este enlace menciona que los procesos de obtener y asignar valores a propiedades con reflection resultó de 2.5 a 3 veces más lento que hacerlo directamente; además de que la invocación de métodos fue 3.5 a 4 veces más lento con reflection que realizar una llamada directa al método.

Estos resultados claramente no son satisfactorios para una aplicación que posiblemente tendría que atender cientos o miles de peticiones, pero también no es nuestro caso la asignación o lectura de propiedades ni mucho menos la ejecución de métodos utilizando reflection. Los datos que necesitábamos conocer era el rendimiento al instanciar clases utilizando reflection.

A continuación los datos que fueron obtenidos:

Rendimiento de Reflection
  Prueba con Reflection Prueba sin Reflection
Total iteraciones 10,000 10,000
Total de Pruebas 20 20
Promedio (ms): 3,813.44 3,706.60
Media (ms): 3,793.24 3,592.44
Mediana (ms): 3,914.25 3,867.38

 Con estos datos se puede decir que el rendimiento de instanciar clases utilizando reflection es de 0.01 a 0.06 veces más lento que creando las instancias directamente. 

Beneficios:

A continuación mencionaré algunas métricas que son utilizadas en el desarrollo de software que están ligadas al código fuente y cómo el uso de Reflection podria ayudar a mejorarlas:

Mantenibilidad: Cómo se puede observar, ambos códigos (con Reflection y sin él) son fácilmente mantenibles ya que si existe un cambio en los procesos de una implementación, sólo tendríamos que modificar la clase correspondiente.

Complejidad Ciclomática: Esta métrica se ve mejorada al utilizar reflection ya que cómo podemos observar no necesitaremos la sentencia ‘switch / case’ para la creación de los objetos con las implementaciones deseadas.

Líneas de código: Las líneas de código también se ven reducidas considerablemente al hacer uso de Reflection.  }

Bajo acoplamiento: Debido a que la construcción se basa en un 'diccionario' de implementaciones, si se deseara que los procesos requeridos para comunicar X con Y ya no es la clase 'ImplementacionXY y en su lugar se utilizaría NuevaImplementacionXY; utilizando Reflection sólo se tendría que modificar el diccionario y no todas las porciones de código que hicieran referencia a esa clase (cómo sería con la instanciación directa). 

Conclusiones:

Utilizar .NET Reflection indiscriminadamente en nuestras aplicaciones hará que el rendimiento de ejecución sea bastante pobre; sin embargo, si se planea bien las arquitectura y las estrategias para utilizar .NET Reflection, el costo de utilizar esta poderosa API no es alto si se consideran los beneficios que se pueden obtener.

Si se desea conocer las buenas practicas de programación al utilizar reflection, pueden leer este excelente artículo: Dodge Common Performance Pitfalls to Craft Speedy Applications

Código Fuente:


Actualmente calificado con 5.0 por 1 personas

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Qué es ASP .NET Control Extenders?

febrero 11, 2009 06:29 by Admin
Aqui dejamos un aporte de la comunidad enviado a través de la seccion de Foro (foro.barreteros.net), este fue enviado por nuestro amigo Johnatan Flores Carmona [johnatan.jfk@gmail.com], el es un Desarrollador .NET de la ciudad de León Guanajuato, aquí dejo el aporte:
------------------------------------------------------------------------------------------
Saludos a todos de nuevo, espero que tengan un bonito día festivo. Y ya que yo tuve que venir a trabajar a pesar de que toda la empresa descansó, estoy aquí para compartir con ustedes otro tema que tuve que investigar hace un tiempo, espero les sea de utilidad. 

  

Qué es ASP .NET Control Extenders?

ASP .NET Control Extenders son controles que derivan de la clase base ExtenderControl (System.Web.UI) la cual puede ser usada para agregar funcionalidad adicional (usualmente soporte AJAX o JavaScript) a controles declarados dentro de una pagina. Esto habilita a los desarrolladores el encapsulamiento de comportamientos IU, y hacer muy fácil agregar funcionalidad a una aplicación web. Un ejemplo de esto es el ASP .NET AJAX Control Toolkit (1)

Según MSDN Library: "La clase ExtenderControl permite mediante programación agregar funcionalidad AJAX a un control de servidor ASP .NET. El ExtenderControl hereda desde la clase Control e implementa la interfaz IExtenderControl. La clase Control define las propiedades, métodos y eventos que son compartidos por todos los controles de servidor ASP .NET. La interfaz IExtenderControl es una clase abstracta la cual no puede ser instanciada directamente. En su lugar debes crear un tipo derivado." (2)

  

Pasos para crear un control extendido

  1. Crear clase abstracta base que hereda ExtenderControl
  2. Crear el archivo .js que implementará el comportamiento de IU (ECMAScript)
  3. Crear una clase que herede de la clase creada en 1 la cual será el extensor del control.
  4. Utilizar el control en una pagina .aspx

En las siguientes secciones se explicarán los pasos necesarios para crear un extensor de control que permite cambiar el estilo al control cuando el mouse pase encima de el.

  

Crear clase base que hereda de ExtenderControl

Cuando se crea una clase que herede de ExtenderControl se requiere que se implementen los métodos abstractos GetScriptDescriptor y GetScriptReferences.

public abstract class ExtenderControlBase : ExtenderControl
{
   protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors(Control targetControl)
   {
      throw new NotImplementedException();
   }
   protected override IEnumerable<ScriptReference> GetScriptReferences()
   {
   throw new NotImplementedException();
   }
}
  • GetScriptDescriptor: Método usado para obtener una colección de descriptores script que representan los componentes cliente ECMAScript (JavaScript).
  • GetScriptReferences: Método usado para obtener una colección de objetos ScriptReference que definen los recursos script que el control requiere.

  

GetScriptDescriptors

Este método debe regresar una colección de objetos ScriptDescriptor que definen que propiedades serán pasadas a la representación del control en el lado del cliente.

protected override IEnumerable<ScriptDescriptor> GetScriptDescriptors(Control targetControl)
{
   ScriptControlDescriptor descriptor = new ScriptControlDescriptor(this.GetType     
                                          ().FullName, targetControl.ClientID);
   descriptor.AddProperty("id", this.ClientID);
   PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(this);
   foreach (PropertyDescriptor property in properties)
   {
      ExtenderControlPropertyAttribute propertyAttribute =
            property.Attributes[typeof(ExtenderControlPropertyAttribute)] as
            ExtenderControlPropertyAttribute;
      if (propertyAttribute != null)
      {
          object value = property.GetValue(this);
          string name = (propertyAttribute.Name != null) ?
                            propertyAttribute.Name : property.Name;
      if (value != null)
             descriptor.AddProperty(name, value);
   }
   }
   yield return descriptor;
}

En el código anterior se crea el objeto que contendrá todas las propiedades que contendrá nuestro control; para ello se obtiene la colección de propiedades que contiene nuestra clase (la clase hija que se creará en el paso 2). Una vez obtenida la colección se recorrerán cada uno de los objetos contenidos y se agregan al descriptor con el método .AddProperty

  

GetScriptReferences

Este método regresará una colección de objetos ScriptReference para incluirlos en la pagina del lado del cliente.

protected override IEnumerable<ScriptReference> GetScriptReferences()
{
   object[] scriptReferences = Attribute.GetCustomAttribute(
   this.GetType(), typeof(ScriptReferenceAttribute), false);
   foreach (ScriptReferenceAttribute sra in scriptReferences)
       yield return sra.GetScriptReference();
}

  

Crear el archivo ECMAScript

Este archivo es el que contiene todo el código (JavaScript) que controla los comportamientos que tendrá el control extendido. A continuación se presenta el bloque de código base que debe tener este archivo.

Type.registerNamespace("CustomAjaxControlKit");
CustomAjaxControlKit.MouseOverExtender = function(element){
   CustomAjaxControlKit.MouseOverExtender.initializeBase(this,[element]);
};
CustomAjaxControlKit.MouseOverExtender.prototype = {
   initialize: function(){
      CustomAjaxControlKit.MouseOverExtender.callBaseMethod(this, "initialize");
   },
   dispose: function(){
      CustomAjaxControlKit.MouseOverExtender.callBaseMethod(this, "dispose");
   }
};
CustomAjaxControlKit.MouseOverExtender.registerClass  
      ("CustomAjaxControlKit.MouseOverExtender", Sys.UI.Behavior);
Sys.Application.notifyScriptLoaded();

El código anterior debe modificarse para que se vea cómo el código siguiente:

Type.registerNamespace("CustomAjaxControlKit");
CustomAjaxControlKit.MouseOverExtender = function(element){
   CustomAjaxControlKit.MouseOverExtender.initializeBase(this, [element]);
   this._MouseOverCssClass = null;
   this._MouseOutCssClass = null;
   this._mouseOverHandler = Function.createDelegate(this, this._onMouseOver);
   this._mouseOutHandler = Function.createDelegate(this, this._onMouseOut);
};
CustomAjaxControlKit.MouseOverExtender.prototype = {
   initialize: function(){
      CustomAjaxControlKit.MouseOverExtender.callBaseMethod(this, "initialize");
      var targetElement = this.get_element();
      $addHandler(targetElement, "mouseover", this._mouseOverHandler);
      $addHandler(targetElement, "mouseout", this._mouseOutHandler);
},
   dispose: function(){
      var targetElement = this.get_element();
      $removeHandler(targetElement, "mouseover", this._mouseOverHandler);
      $removeHandler(targetElement, "mouseout", this._mouseOutHandler);
      CustomAjaxControlKit.MouseOverExtender.callBaseMethod(this, "dispose");
   },
   get_MouseOverCssClass: function(){
      return this._MouseOverCssClass;
   },
   set_MouseOverCssClass: function(value){
      this._MouseOverCssClass = value;
   },
   get_MouseOutCssClass: function(){
      return this._MouseOutCssClass;
   },
   set_MouseOutCssClass: function(value){
      this._MouseOutCssClass = value;
   },
   _onMouseOver: function(eventArgs){
      var targetElement = this.get_element();
      if(targetElement != null)
         targetElement.className = this.get_MouseOverCssClass();
   },
   _onMouseOut: function(eventArgs){
      var targetElement = this.get_element();
      if(targetElement != null)
         targetElement.className = this.get_MouseOutCssClass();
   }
};
CustomAjaxControlKit.MouseOverExtender.registerClass     
                     ("CustomAjaxControlKit.MouseOverExtender", Sys.UI.Behavior);
Sys.Application.notifyScriptLoaded();

  

Crear la clase que será el extensor del control

Debido a que se creó una clase abstracta base que hereda de la clase ExtenderControl (véase el paso 1), la creación de nuestra clase que será el extensor de control simplemente debe agregar la WebReference del archivo ECMAScript, heredar la clase ExtenderControlBase y agregar las declaraciones de las propiedades que tendrá nuestro extensor de control.

A continuación se muestra el código de nuestra clase:

[assembly: WebResource("CustomAjaxControlKit.MouseOver.MouseOverBehavior.js",
                                                         "text/javascript")]
namespace CustomAjaxControlKit
{
   [TargetControlType(typeof(Control)), ScriptReference(
        "CustomAjaxControlKit.MouseOver.MouseOverBehavior.js", CustomAjaxControlKit")]
   public class MouseOverExtender : ExtenderControlBase
   {
      [ExtenderControlProperty]
      public string MouseOverCssClass { get; set; }
      [ExtenderControlProperty]
      public string MouseOutCssClass { get; set; }
   }
}

  

Utilizar el extensor de control en una pagina .aspx

Para poder utilizar nuestro extensor de control en una pagina .aspx tenemos que primero agregar la referencia al dll que contiene el código de nuestro extensor. Una vez realizado esto se debe incluir la directiva @Register para poder incluir en la pagina los tags de nuestro control: 

<%@ Register Assembly="CustomAjaxControlKit" Namespace="CustomAjaxControlKit" TagPrefix="cack" %>
Por último debemos agregar el control que sufrirá los efectos de nuestro extensor y a continuación declarar nuestro control:
<asp:Label runat="server" ID="Label1" Text="Texto prueba" />
<cack:MouseOverExtender ID="MouseOverExtender1" runat="server" TargetControlID="Label1"  MouseOutCssClass="MouseOutStyle"
                       MouseOverCssClass="MouseOverStyle" />

  

Ejemplo: Codigo Fuente

Si deseas ver el código fuente completo de este control puedes descrgarlo en el siguiente link:

  

Referencias

  1. ScottGu; Using ASP .NET AJAX Control Extenders in VS 2008; http://weblogs.asp.net/scottgu/archive/2007/08/19/using-asp-net-ajax-control-extenders-in-vs-2008.aspx
  2. MSDN Library; About ExtenderControl Class; http://msdn.microsoft.com/en-us/library/system.web.ui.extendercontrol.aspx

Sea el primero en calificar este post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Integración Multiempresas

diciembre 2, 2008 06:06 by sergio
Conforme las empresas han ido adquiriendo la necesidad de realizar negocios haciendo uso de las TI, su competencia para realizar negocio ha ido incrementándose significativamente. El fenómeno B2B ha envuelto diferentes aplicaciones, desde el Intercambio Electrónico de Información (EDI) hasta la compra de bienes y servicios que demanda flexibilidad y automaticidad al momento de interactuar con socios comerciales.

Muchos proyectos multiempresa están proliferando, desde el comercio electrónico tradicional, hasta la integración y conectividad entre sistemas, proveyendo de las bondades del software como servicios y los procesos de negocios como integraciones de servicios.

Otro conductor ha sido el aumento de presión en la industria para acortar los procesos de negocio críticos y de ejecución, tiempos de ciclo y por tanto, más procesos de cambio orientados a la interacción del tiempo.

Las empresas están más inclinados a tomar ventaja de servicios Web en diversos proyectos de TI, así como la aplicación proveedores (tales como Oracle y SAP), Proveedores de middleware (por ejemplo, Tibco y webMethods de Software) y B2B proveedores (como Axway y Sterling Commerce). El interés en los servicios Web ha sido impulsado por el éxito de su uso debido a su integración y su gran interoperabilidad.

Sin embargo, mientras aumenta la adopción de tanto SOA y los servicios Web, los enfoques tradicionales e interoperabilidad (entre ellos AS2, EDI, transferencia de archivos, XML / HTTP y RosettaNet) seguirá siendo útil. De hecho, en muchos proyectos, el uso de los enfoques tradicionales seguirá ampliando.

Actualmente calificado con 1.0 por 1 personas

  • Currently 1/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tenemos responsabilidad en lo que enseñamos/ mostramos?? … o simplemente nos dejamos llevar por las modas…

noviembre 28, 2008 07:07 by ddaz

El post que saco hace unos días Jorge  sobre el por que quitar las referencias a VB  hizo que vuelva a mi mente unas cosas que tenia ya hace tiempo en la cabeza… y bueno, Jersson hizo que me anime a publicarlo. 

Problema :

lo que pensaba era si nosotros como expositores, divulgadores de tecnología ( que no sean empleados MS), entusiastas, etc.. somos responsables de las cosas que mostramos o damos a conocer a los demás…  ya que como una vez me dijo  Fer:

“muchas veces las personas –los lectores- toman muy en serio las cosas que decimos -escribimos-, así que se tiene que tener cuidado con lo que se dice –escribe-  públicamente”

Lógicamente  cada persona es libre de poner lo que le plazca en su blog/web/twitter, etc. pero creo que es necesario que seamos un poco mas consientes de la imagen que damos, a que me refiero?…  supongamos que sale una nueva funcionalidad, característica, etc.… lógicamente es publicada en su mayoría al inicio por algún empleado ms,  o algún socio, donde habla de esa funcionalidad, lógicamente por lo mismo de que es “ un negocio”  solo dirán el lado bonito,  lo bueno, pero no dirán “lo que viene por detrás” , el costo de usar esa funcionalidad, y muchas veces caemos en el error de “copypastear”  la noticia y publicarla así tal cual, sin haber antes probado…, o bueno quizá hasta allí podría pasar como “noticia”, pero lo mas correcto seria “quizá”  que probemos a profundidad esa funcionalidad, para poder ser capaz  de dar una opinión.

Otro problema muy común, es que solo probamos lo bonito, y no nos fijamos en lo demás, llegamos hasta dar conferencias o a hablar del producto, pero sin antes haber investigado sobre el costo de usar eso, personalmente siento que no se conoce realmente algo, hasta que se sabe su lado bueno y malo, cuando encuentro algo nuevo, busco lo bueno y a su vez – no por negativo- busco el costo de usarlo, y luego hago un balance entre lo bueno y lo malo, y si gana lo bueno lo uso…; e platicado con  varias personas  sobre determinadas tecnologías que usan, y les preguntaba si conocían determinado “ problema” que tendrían por usar esa tecnología ( para saber si eran consientes de eso), pero resultaba en muchos casos que ni sabían de eso, pensaban que todo era maravilloso. Lógicamente si uno es consiente de lo bueno y lo malo  y aun así decide usarlo, eso es algo para respetar, ya que tomo su decisión  conociendo realmente lo que esta usando.

Creo que es malo usar “en producción”  o recomendar masivamente que lo usen “en producción”  algo que no conocemos a fondo, muchas veces por querer ser “early adopter’s”   ponemos en producción cosas que nosotros no hemos probado a profundidad,  el lio es que cuando salen los problemas… volvemos a lo mismo “es culpa de MS” . También creo que es malo dejarnos llevar ciegamente por lo que podamos leer en blogs/webs/ conocidas , si bien es cierto muchos de nosotros somos socios “partner’s”  de Microsoft, y usamos sus tecnologías, y podemos leer una noticia  de alguna nueva tecnología”  y sin refutar, nos ponemos a usarla “en producción”  a fondo como si fuera esa tecnología perfecta y lo recomendamos a otros,  y luego si sale una nueva que se sobrepone a esta que estamos usando, sin refutar ni investigar a fondo nos ponemos a migrar a esa nueva funcionalidad, gastando recursos por algo que quizá funcionaba bien… y esto por que???? … por las “Modas” 

En estos círculos “.Net” llegue a reconocer a varios tipos de usuarios de tecnologías Microsoft, lógicamente  hay personas que si respeto mucho, ya que no se dejan llevar por la promoción investigan y sacan sus propias opiniones, esto en base a investigación propia, además de posibles referencias en el internet. También están las personas que no investigan y se creen todo lo que leen,  casi casi hasta lo que aparece en la web “el día de los inocentes”   y lo toman como “ ley”  y  muchas veces lo defienden a muerte, el problema en este caso es cuando estas personas son expositores, o divulgadores de tecnología, y sin haber tener una opinión propia bien fundamentada, replican eso y se genera el efecto del telefonito malogrado;  en muchos casos son conocidos como los que simplemente se memorizan la ppt y lo repiten  tal cual – e visto varios eventos, de ponentes diferentes,  donde se dice exactamente lo mismo, como si fuera el Avemaria –.Los que siguen Modas, estas personas no tienen una preferencia real, usan y siguen lo que este de “moda”, si la moda cambia, ellos cambian, algunas veces dura dias o meses. También están los Incondicionales, de los que defenderán a MS a muerte, saque la tecnología que saque, a mi parecer estos son los mas peligrosos, por que puede llegar a ser que hayan investigado a fondo ( casi no lo hacen, pero seamos optimistas ), pero por el simple echo de quedar bien, mostrarse “actualizados” ( o muchos otros motivos, el cual prefiero no mencionar… pero son conocidos), estas personas son de las que intentarían vender refrigeradoras a los esquimales –ósea no les importa si les sirve o no, lo que importa es darles lo ultimo-, recuerdo una vez que platicaba con una persona y defendía a muerte a Virtual PC 2004, decía que era mucho mejor que el vmware…, me atreví a preguntarle que si lo había usado… y me dijo que no, “ pero que en la web decía que era lo máximo”, lógicamente la platica allí termino… quizá haya otra categoría que se me haya pasado…  en este momento no la recuerdo.

 

Consecuencias :

Si, en este punto muchas personas estarán pensando “ yo soy libre de poner lo que quiera”  y no se equivocan, el detalle es … se habrán dado cuenta de las consecuencias de eso?, de que tanto pueden influir en los lectores? ….

Aquí unos ejemplos de cosas en las cuales AHORA ya no vemos bien ( o al menos de cierto modo) y en las cuales muchos hemos caído ( tengo que aceptar que en el primer caso yo caí … y fue la ultima vez que me deje llevar):

Dataset : cuando salió .Net el Dataset era el boom, si bien es cierto en muchos casos es útil, pero eso luego de un análisis de costo/beneficio, pero en el tiempo en que salió 2002/ 2003 era el boom, así que todos lo usaban , casi todos exponían de eso, de la facilidad, de lo corto del código, del dataadapter.fill y el dataadapter.update, ya hasta que se vieron los problemas en “producción” de performance se comenzó a cambiar la idea, aquí tengo que aceptar que yo tbm fui victima de esto, el detalle es que este “ problema” aun no termina, ya que en muchos de los ejemplos del MSDN – y otros website-  se usan como ejemplos los dataset,  si bien es cierto muchos ya estamos usando las listas genéricas y entidades en el acceso a datos, información  casi no se encuentra “públicamente” y las personas que recién están aprendiendo, verán que se usa dataset y lo usaran en producción, e visto grandes sistemas llenos de dataadapters y datasets en producción, y me llamaban ya que no entendían “por que era tan lento, si estaba echo en .net”.

Ajax : Este es reciente, en este caso es una buena tecnología, pero muchas veces no informamos bien el problema de no usarlo bien, y los usuarios se ponen a poner a diestra y siniestra updatepanels y demás sobresaturando sus paginas, lo bueno es que ahora ya en muchos lugares e visto donde recomiendan usarlo con moderación, pero eso no era así al inicio.

My: de esto se trata  el post de Jorge  sobre el por que es bueno quitarlo…, el detalle es que cuando salió vs 2005, esto fue uno de los caballitos de batalla.

Este ultimo es una opinión personal, aunque posiblemente muy controversial

Linq2SQL : bueno en este caso.. y en esta batalla estoy “casi solo” ( al menos en geeks.ms ), ya que “por el momento” soy de las pocas personas que no esta muy a favor de esto en especifico ( aunque la idea de Linq en general me parece buena, como Linq2Entity), ya Jersson publico unas pruebas de performance, además de que en un articulo se habla de la posible desaparición de Linq2SQL:  http://tinyurl.com/56d5ze , y  es algo en lo que estaría muy de acuerdo, Jersson me dijo que “tengamos paciencia, ya llegara ese día”, algo que espero; lógico hay quienes realmente han visto su lado bueno y malo, lo evaluaron y aun así decidieron usarlo, allí no podría decirles nada, ya que según su evaluación costo/beneficio les convenía usarlo, si fuera este el caso, es el tipo de cosas que hacen que respete a las personas.

Conclusiones :

Esos fueron ( al menos de los 3 primeros) ejemplos de tecnologías que son comúnmente muy “ mal usadas” por los programadores sin experiencia, y esto por que? por que vieron en algún blog, una conferencia, un webcast, que se usaba de cierto modo, y no tuvieron el aviso de que “solo servía como demostración, y no para entornos reales”; lógicamente esto es algo bueno para los de consultoría, ya que cobrarían ( y muy bien)  para arreglar ese tipo de situaciones :) .

Seria recomendable que cada uno haga una introspección y vea si lo que uno “predica” es algo que realmente conoce, si esta uno ya evaluó lo bueno, lo malo,  y aun así decide usarlo; si alguien hace la evaluación y  siente que determinada tecnología que usa es la mejor a su parecer, es algo de respetar, ya que en software, no hay “ respuesta correcta”, creo que lo correcto para todo seria la palabra “depende” , pero  todo usándolo luego de una evaluación, es malo si usamos las cosas sin antes evaluar bien la situación;  Seria Tan valido usar el GOTO en Vb si luego de una evaluación  vemos que es algo que nos conviene – ya esta probado que ms en el IL genera sentencias GOTO – esto en el blog de Rafael Ontivero - , supongo que MS evaluó y vio que era lo mejor-.

para terminar, solo me queda decir que seria bueno que pensemos no solamente en lo que ponemos, sino también como lo recibirán nuestros lectores y como podríamos afectarlos.

“No Siempre lo ultimo y lo mas voceado es lo mejor, primero analicemos, si realmente conviene usarlo, si luego de una evaluación profunda vemos que nos convence, entonces allí si  comencemos a recomendarlo a nuestros conocidos, ya que tendríamos un buen fundamento”. Dacito.

Pdta:  si se fijan, aclare de personas “No empleadas de MS”, ya que es razonable y lógico que los empleados MS defiendan sus tecnologías, ya que es una empresa privada y esas tecnologías son parte de su negocio, por eso mismo debemos de tomar con pinzas todas las noticias o lanzamientos que hacen.

Pdta2:  si llegaste a leer hasta aquí… ya tienes mis respetos, por el aguante, y espero no haber ofendido a nadie, si  es que llegue a hacerlo, de antemano le pido una disculpa.

Salu2

David Daniel Arroyo Zari – Ddaz -


Actualmente calificado con 5.0 por 2 personas

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Fundamentos de Administración de Proyectos - Segunda Entrega

noviembre 22, 2008 13:12 by sergio

2. Gestión del Alcance del Proyecto

La Gestión del Alcance del Proyecto incluye los procesos necesarios para asegurarse que el proyecto incluya todo el trabajo requerido, y sólo el trabajo requerido, para completar el proyecto satisfactoriamente. La gestión del alcance del proyecto se relaciona principalmente con la definición y el control de lo que está y no está incluido en el proyecto.

Descargar aquí el Documento


Actualmente calificado con 3.0 por 2 personas

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5