Que trae de nuevo el .NET Framework 4.5?

El siguiente articulo es una traduccion del articulo de Rob Sanders, acerca de sus anotaciones de lo observado en el TechEd-Australia, contiene los elementos nuevos que trae el .NET Framework 4.5.

Introduccion

Arrancamos… un poco de discusion acerca de la historia del .NET Framework, el cual tiene ahora 10 anios. El panorama es bastante breve, los presentadores estan bastante relajados y trabajan fluidamente entre ambos.

  • Cuales son los elementos clave que trae la version 4.5?
  • Mejoras en la funcionalidad asincrona
  • Windows 8 y Windows 8 RT
  • Nuget y paquetes distribuibles
  • Un framework mas ligero con los paquetes Nuget.
  • Rendimiento
  • Usuarios y retroalimentacion de la comunidad

Core Framework

Asynchronous/Waits [Demo]

Mostrando el uso de async/await dentro del contexto de una interface WPF. Se requiere mucho menos codigo que lo que tradicionalmente se requeria, en especial con relacion al UI Thread Marshalling.

Estamos revisando el ensamblado, naturalmente usando .NET Reflector. Cuando utilizamos async/await el compilador genera una gran cantidad de codigo por debajo. Tenga esto en mente cuando piense usar async/await. No es ideal para pequenas aplicaciones.

Las clases base del namespace IO ahora son compatibles con async. Stream/TextReader/Writer/etc. Cambiando de tema…

Identity

Revision de los usos historicos de Iidentity, Iprincipal, etc. Capacidades basicas en membership y roles, ausencia de acceso a mas informacion (por ejemplo el email)

El framework 4.5 se convierte en mas claim-aware. Nueva clase ClaimsIdentity (la cual implementa IIdentity) , la cual permitira el uso de claim-tokens en las aplicaciones. Hay varios metodos helpers que ayudan en la navegabilidad. Otras clases Principals heredan de esta clase. Compatibilidad hacia atras para aplicaciones antiguas.

Active Directory en el Serve 2012 ahora puede exportar claims-tokens. Windows Identity Foundation ahora esta integrado en e. Framework 4.5 (no mas instaladores separados) [N.T: Al fin]

Librerias Portables de Clases

Aunque estoy bastante seguro de que esta caracteristica fue introducida en el Fx .NET 4.0?. Ah, Este fue separado del framework base en su version 4.0

[Demo]

El soporte esta incluido en los proyectos de Visual Studio. Evita la necesidad de definiciones de pre-compilador.

[N.T.: http://channel9.msdn.com/Shows/Visual-Studio-Toolbox/Visual-Studio-ToolboxPortable-Class-Libraries ]

Otras cosas

  • Optimizaciones del Profile y Multicore JIT
  • Timeout para expresiones regulares (regex) (probablement no es una mala idea)
  • Nuevo namespace para el nuevo soporte de compresion zip, supongo que los problemas de licencias estan resueltos?
  • Referencias debiles – cambios de tipo en caso de que un objeto sea destruido (disposed)
  • Internacionalizacion (cultura) dentro de un app-domain (bueno por unas pocas razones)

Cosas web

  • Modelo de programacion HTTP (lease aplicaciones RESTful)
  • Soporte completo para enrutamiento (MVC?)
  • Negociacion del contenido
  • Composicion de consultas (QueryString)
  • Aplicaciones auto-hospedadas (self hosted)

Las operaciones CRUD pueden ser mapeadas a verbos HTTP (GET/POST/etc). Soporte de programacion HTTP mejorado en el Fx .NET 4.5. Se incluye negociacion de contenido, de manera nativa. Filtrado de contenido al vuelo usando WebAPI [Demo]

Mehesh esta mostrando las peticiones/respuestas HTTP en tiempo real. Estamos viendo el flujo de datos JSON en la respuesta. Ahora esta mostrando como la respuesta puede ser cambiada para retornar un XML basico. Funcionalidad incorporada. Referencia al Sr. Philip Beadle (famoso por DotNet-Nuke)

Agregando un controlador, agrega el codigo de manejo apropiado. Se necesita tener un manejador de excepciones, por lo demas todo esta en su lugar.

HTTP Client

La clase HttpClient puede ser usada para instanciar programaticamente un objeto cliente Http, bastante util para ejecutar peticiones get y evaluar respuestas, etc.

Web Sockets

La tecnica de Polling ha sido usada durante mucho tiempo como una aproximacion de busquedas. Se puede mejorar? Establecer una conexion con una llamada normal. Comunicacion bi-direccional Full-duplex, Soporte para proxies integrado, Soporte binario, UTF-8.

Soporte en IIS 8, ASP.NET 4.5, WinRT, WCF 4.5 sobre Windows 8 y Windows Server 2012.

[Demo – Aplicacion de un chat usando Web-Sockets]

El mensaje es enviado al servidor, el servidor hace un broadcast a los usuarios.

Un poco decepcionante verlo ejecutandose en una sola computadora y con solo dos usuarios. Momento de ver codigo.

El HttpHandler verifica la peticion, se enruta al handler si la peticon es una peticion web-socket. Me gustaria ver que esto se concretase un poco mas.

ASP.NET Web Forms

  • Controles de datos fuertemente tipados (finalmente!)
  • Soporte mejorado para async
  • Minificacion integrada de js/css
  • Controles de servidor actualizados para generar HTML5

MVC

  • Mejoras en Razor
  • Cambios al template por defecto
  • Async, async!
  • Soporte para dispositivos moviles mejorado.

Viendo un demo de ASP.NET . Enlace de datos (Data-bindig) con controles fuertemente tipeados, bye bye eval(). La demostracion muestra validacion, enrutamiento (ya no se observa la extension .aspx en el URL) e interpretacion mejorada del query string. Aun se registran rutas en una forma que no es novedosa para los programadores MVC.

WCF

  • Simple de configurar (finalmente!) Los valores por defecto ahora son mas sensibles
  • Los proxies que se generan, ahora definen metodos async por defecto!
  • Se pueden crear tareas (tasks) basadas en operaciones asincronas.
  • Web-Sockets (como se menciono previamente), se requiere un paquete Nuget.
  • Soporte para el protocolo UDP (datagramas!)
  • Un API de control mejor expuesto a travez de codigo.
  • El uso de la operacion "Configure"para recuperar en tiempo de ejecucion la configuracion definida. (N.T. genial!)
  • Soporte WCF para aplicaciones Windows 8.

[Demo – WCF y una aplicacion Windows 8] Nota: Usando Entity Framework (buenisimo)

Observar que los metodos sync y async son generados en los proxy cliente. Los metodos async no estaban habilitados por defecto en el pasado. Los clientes Windows 8, no soportan operaciones sync – solamente operaciones async (debido a las consideraciones de bloqueo de las UI Metro o como se llamen ahora). No se ven archivos de configuracion para las aplicaciones Windows 8. El demo falla auch!

WPF

  • Los controles Ribbon ahora estan integrados
  • Validacion asincrona
  • El enlace de datos (data-binding) ha cambiado
  • Enlace retrazado – delay binding (tal vez por async)
  • Enlace a propiedades estaticas
  • Extensioes de marcado (XAML) para eventos

[N.T. Me pregunto si todo lo de XAML tambien se aplica a Windows Phone]

WF

  • Expresiones C# soportadas
  • Servicios Workflow con el modelo Contract-First
  • Versionamiento de Workflow (finalmente integrado). Se carga correctamente el workflow con la actividad.
  • Mejoras en los disenadores (de nuevo… finalmente!)
  • Soporte de comentarios y navegacion mejorada.

Otras cosas interesantes (Parte 2)

MEF 2.0

Esto se acerca a un framework IoC para mocking e inyeccion de dependencia.

  • Soporte para abrir partes genericas
  • Registro basado en reglas y convenciones
  • Construccion de reglas para importar/exportar sin declaraciones/atributos.
  • Mejoras de ambito
  • Mejoras en el diagnostico.
  • Pensadas para aplicaciones Web y Metro

Pensamiento rapido: Nada en el compilador en tiempo de ejecucion (Roslyn?)

El TPL (Task Parallel Library)

El Task Parallel Library… se ve bastante bien:

  • Mejoras en el rendimiento
  • Nuevos metodos:
    • Run
    • Delay
    • WhenAny
    • WhenAll
    • FromResult
  • La clase Progess<T>

TPL Data Flow

Mirando a los sistemas reactivos – flujos de datos en memoria, controles basados en agentes. Nueva libreria .Net.

Esto es algo en lo que voy a estar bastante interesado en probar. Para tener mas informacion acerca de TPL data Flow, mantengase atento a la Tecnologia Sanders

  • Conjunto de bloques (primitivas)
  • Queue/buffer/Task
  • EG ActionBlock/TransformBlock/BufferBlock

Demo rapido del nuevo TPL data Flow. Estamos llegando al final brevemente.

Conclusion

No es una version menor, tiene un gran soporte para Windows 8, async y mejoras de rendimiento. Aqui finalizamos.

[N.T.]

El articulo original pueden encontrarlo aqui: 

http://www.sanderstechnology.com/2012/whats-new-in-net-4-5/11488/#.UFUQL42PXiu

En aras de mantener el sentido de la traduccion mantuve algunos terminos en su version en ingles, sepan por favor disculpar esta mezcla Smile

Mi granito de arena: Un inclusion esperada en el Framework 4.5 es Code Contracts, al fin podemos usarlo sin tener que hacer referencias externas.

Gracias por la paciencia de leer hasta aqui.

Un saludo.

Episodio 2–Arquitectos.NET Podcast

Una vez mas, estimados amigos, nos reunimos con Andres Gonzales y grabamos el segundo episodio del podcast que hemos venido a llamar “Arquitectos.NET”, en esta ocasión el tema de nuestra conversación son “Las arquitecturas de Servicios SOA y REST”, hemos querido centrar la charla en nuestras experiencias y recomendaciones y de ahí que surge el siguiente temario básico:

 

  • Definición e historia de las arquitecturas SOA y REST
  • Problemas que se intentan resolver con SOA/REST
  • Protocolos involucrados: WSDL, SOAP / WS-*
  • Peligros y equivocaciones posibles
  • Seguridad
  • Esquemas de n capas
  • Enterprise Service Bus
  • Cuándo aplicar SOA/REST y cuándo no.
  • Menciones a casos reales de uso de SOA/REST

Para aquellos que no tengan flash instalado o que deseen guardar este archivo, aqui les dejamos el enlace, también pueden dirigirse a esta página para ver el reproductor online.

Continuamos con nuestro aprendizaje en esto de hacer podcasts y en esta ocasión, tenemos algunos problemillas en el audio, que espero nos sepan disculpar:

  • Unos cortes de audio producto de la edición post-grabación (les aseguro que no se perdieron algo muy importante)
  • Mi mascota ladra en el fondo, en algunos momentos

Luego de haber recibido buenos comentarios y un excelente “feedback”" de varios amigos escuchas, los invitamos nuevamente a hacernos llegar sus sugerencias e ideas para futuros podcasts. También están abiertas las puertas para recibir participantes invitados que quieran conversar con nosotros acerca de aquello que más nos gusta: la tecnología y el desarrollo de software. Esta invitación no ha caído en saco roto y el siguiente podcast contaremos con un invitado, que muchas personas en nuestro país conocen (es una sorpresa).

Para centralizar todos vuestros contactos pueden hacernos llegar sus correos electrónicos a la dirección arquitectos.net@outlook.com.

Un saludo y hasta la siguiente emisión.

Episodio 1–Arquitectos.NET Podcast

Estimados amigos, quiero presentarle a Uds. el primero de varios podcast que iremos grabando junto a mi apreciado amigo Andres Gonzales. El plan inicial es tener varias conversaciones acerca de aquello que mas nos gusta hacer, desarrollar software, también estaremos invitando a personas conocidas en nuestro medio, para conocer sus puntos de vista y opiniones acerca de diversos temas.

En esta ocasión quisimos conversar acerca de “Una comparativa entre ASP.NET WebForms vs ASP.NET MVC”. Un tema algo conocido pero del que podemos generar muchas horas de conversación. El temario básico que tocamos fue el siguiente:

  • Algo de Historia
  • Arquitectura de ambos modelos
  • Seguridad
  • Escenarios de uso WebForms
  • Escenarios de uso MVC
  • Transicion de WebForms a MVC
  • Javascript / jQuery/ HTML/ CSS

Para aquellos que no tengan flash instalado o que deseen guardar este archivo, aqui les dejamos el enlace, tambien pueden dirigirse a esta pagina para ver el reproductor online.

Como somos principiantes en esto de los podcast, espero sepan disculpar nuestros errores, entre ellos:

  • En algun punto de la grabacion se menciona PHP.NET y como bien dice Andres esto es una “..condenada costumbre de añadir .NET a todos los lenguajes XD”.
  • Hay algun corte casi imperceptible en el audio y esperamos que no sea algo que impida entender algunos de los conceptos de los que hablabamos en esos momentos.

Enlaces con mas informacion:

Nos gustaria leer sus comentarios, opiniones y sugerencias para futuros podcasts, quiza alguno de Uds. quiere participar de nuestras grabaciones y compartir con nosotros sus experiencias y conocimientos, todo ello es bienvenido, con tal finalidad aqui les dejamos nuestros correos electronicos:

Esperamos que les haya gustado.

Saludos

Un arbol con jsTree y ASP.NET MVC (II) – Poblando Datos

Luego del primer post de la serie, donde muestro como instalar y configurar jsTree, aqui les mostrare como poblar datos en el arbol.

jsTree, tiene lo que el llama un JSON_DATA plugin, mas informacion referida a esto la pueden encontrar en su documentacion aqui, la siguiente imagen muestra una captura de pantalla de la pagina de documentacion.

image

Como podran observar el tema no es muy explicativo que digamos y las multiples preguntas empiezan a aparecer, como usar jsTree con MVC, como le cargo datos, etc, etc.

El primer paso es definir un contendor que sera el lugar donde el arbol sera renderizado, para ello creamos una vista llamada DemoTree que tiene la siguiente apariencia general y dentro definimos un div, tal como muestro a continuacion, el div e este caso se llama “componentsTree”:

image

Luego de tener el div establecido necesitamos invocar al plugin, para ello utilizamos jsTree y su metodo de inicializacion, tal como se muestra a continuacion:

image

Para que puedan copiar el metodo, se los coloco en su integridad aqui:

1 <script type="text/javascript"> 2 3 $(document).ready(function () { 4 5 $("#componentsTree").jstree({ 6 json_data: { 7 ajax: { 8 //url: $.pathDomain("Puesto/FillComponentsTree"), 9 url: "Puesto/FillComponentsTree", 10 type: "POST", 11 error: function (XMLHttpRequest, textStatus, errorThrown) { 12 }, 13 success: function (data, textStatus, jqXHR) { 14 if ("Saved" in data) { 15 } 16 }, 17 complete: function () { 18 } 19 } 20 }, 21 ui: { select_limit: 1, initially_select: ["#rootComponent"] }, 22 plugins: ["json_data", "ui", "themes"], 23 core: { 24 html_titles: true 25 } 26 27 }).bind("select_node.jstree", function (e, data) { 28 indexNodeSelected = data.rslt.obj.attr('id'); 29 typeNode = data.rslt.obj.attr('typeNode'); 30 featureType = data.rslt.obj.attr('featureType'); 31 32 }).bind("before.jstree", function (e, data) { 33 }); 34 35 }); 36 </script>

El metodo de inicializacion contiene secciones importantes, entre ellas:

  • url: que especifica el Action Method de ASP.NET MVC que sera invocado para cargar el arbol.
  • type: que especifica el tipo de request que se enviara al action method.
  • ui: que especifica valores de inicializacion de jsTree, aqui les propongo la configuracion mas generica que yo utilice. Para mas informacion consultar la documentacion.
  • eventos: que permiten determinar cuando se cargaron correctamente los elementos del arbol y tambien cuando se selecciono un item del arbol

El segundo paso paso es crear un grupo de clases que seran la estructura de datos que espera jsTree, estas clases C#, luego seran serializadas a JSON, lo que proporcionara la informacion que necesita el plugin.

1 public class JsTreeNode 2 { 3 public TreeAttribute attr { get; set; } 4 5 public Data data { get; set; } 6 7 public string state { get; set; } 8 9 public List<JsTreeNode> children { get; set; } 10 } 11 12 public class TreeAttribute 13 { 14 public string id { get; set; } 15 16 public string rel { get; set; } 17 18 public string mdata { get; set; } 19 20 public string TypeNode { get; set; } 21 22 //public FeatureType FeatureType { get; set; } 23 } 24 25 public class Data 26 { 27 public string title { get; set; } 28 29 public string icon { get; set; } 30 }

En tercer lugar y no menos importante es tener una estructura que almacene datos jerarquicamente, esta estructura puede ser cualquiera que Uds tengan actualmente ya sea que provenga de una base de datos o sean simples datos en memoria. Esta estructura puede parecerse a la siguiente a la siguiente:

1 /// <summary> 2 /// Estructura que soporta la construccion de jerarquias. 3 /// </summary> 4 public class TreeElement 5 { 6 //Importante y Requerido 7 public string Id { get; set; } 8 9 //Importante para mostrar el texto 10 public string Description { get; set; } 11 12 //No relevante y es solo un ejemplo de datos adicionales 13 public string ComponentType { get; set; } 14 15 //Importante y requerido 16 public string ParentId { get; set; } 17 }

La estructura arriba mostrada solo almacena un elemento jerarquico y las propiedades mas importantes son Id y ParentId, esta ultima propiedad es solo el identificador del padre del elemento actual. Estos elementos seran almacenados en una lista como veremos posteriormente.

En cuarto lugar les muestro a continuacion, el grupo de metodos que utilice en el controlador, el mas importante: FillComponentsTree.

1 public ActionResult DemoTree() 2 { 3 return View(); 4 } 5 6 [AcceptVerbs(HttpVerbs.Post)] 7 public ActionResult FillComponentsTree() 8 { 9 try 10 { 11 IList<TreeElement> components = GetElements(); 12 var data = RenderTreeView(components); 13 return data; 14 } 15 catch (Exception ex) 16 { 17 return Json(new {Saved = false, Message = ex.Message }); 18 } 19 } 20 21 private IList<TreeElement> GetElements() 22 { 23 IList<TreeElement> elements = null; 24 var service = new PuestoService(); 25 elements = service.GetElementsForTree(); 26 return elements; 27 } 28 29 private ActionResult RenderTreeView(IList<TreeElement> components) 30 { 31 if (components.Count() > 0) 32 { 33 var parent = (from c in components 34 where c.ParentId == null 35 select c).FirstOrDefault(); 36 37 JsTreeNode rootNode = CreateJsTreeNode(parent); 38 PopulateTree(parent, rootNode, components); 39 40 return Json(rootNode); 41 } 42 return Json(new JsTreeNode()); 43 } 44 45 private void PopulateTree(TreeElement parent, JsTreeNode rootNode, IList<TreeElement> components) 46 { 47 var childs = from c in components 48 where c.ParentId == parent.Id 49 select c; 50 51 if (childs.Count() <= 0) 52 rootNode.state = null; 53 54 rootNode.children = new List<JsTreeNode>(); 55 foreach (var c in childs) 56 { 57 JsTreeNode node = CreateJsTreeNode(c); 58 rootNode.children.Add(node); 59 PopulateTree(c, node, components); 60 } 61 } 62 63 private JsTreeNode CreateJsTreeNode(TreeElement nodElement) 64 { 65 //var fileName = PathDomain + "/Content/treeview/icons/" + c.ComponentType + ".png"; 66 JsTreeNode node = new JsTreeNode() 67 { 68 attr = new TreeAttribute() 69 { 70 id = nodElement.Id, 71 TypeNode = nodElement.ComponentType, 72 //FeatureType = c.FeatureTypesSupported, 73 //rel = c.ToJSON(), 74 mdata = "{ draggable : true, max_children : 100, max_depth : 100 }" 75 }, 76 data = new Data 77 { 78 title = nodElement.Description 79 //icon = System.IO.File.Exists(Server.MapPath("~/Content/treeview/icons/" + parent.ComponentType + ".png")) ? fileName : PathDomain + "/Content/treeview/icons/generic_icon.png" 80 }, 81 state = "open" 82 }; 83 return node; 84 }

Finalmente para los que han podido seguirme hasta este punto, hay una clase llamada PuestoService y que es la que proporciona el metodo GetElementsForTree, este metodo cargara, dinamicamente o estaticamente el arbol de la siguiente manera:

1 public class PuestoService 2 { 3 public IList<TreeElement> GetElementsForTree() 4 { 5 List<TreeElement> arbol = new List<TreeElement>(); 6 arbol.Add(new TreeElement { Id = "1", Description = "Raiz", ParentId = null, ComponentType = "None" }); 7 arbol.Add(new TreeElement { Id = "2", Description = "Mamiferos", ParentId = "1", ComponentType = "1" }); 8 arbol.Add(new TreeElement { Id = "3", Description = "Carnivoros", ParentId = "1", ComponentType = "2" }); 9 arbol.Add(new TreeElement { Id = "4", Description = "Ballena", ParentId = "2", ComponentType = "X" }); 10 arbol.Add(new TreeElement { Id = "5", Description = "Lobo", ParentId = "3", ComponentType = "Z" }); 11 arbol.Add(new TreeElement { Id = "6", Description = "Delfin", ParentId = "2", ComponentType = "X" }); 12 arbol.Add(new TreeElement { Id = "7", Description = "Orca", ParentId = "2", ComponentType = "Z" }); 13 arbol.Add(new TreeElement { Id = "8", Description = "Delfin Botella", ParentId = "6", ComponentType = "E" }); 14 return arbol; 15 } 16 }

La clase PuestoService, puede ser tan compleja como quieran y podria estar recuperando los datos desde una base de datos directamente o quiza utilizar un servicio WCF para tal fin, en este caso nuevamente en aras de mantener la simplicidad cargamos datos estaticamente.

El arbol se muestra tal como en la siguiente captura:

image

Hasta el momento todo esta muy bien, todos los datos definidos estaticamente aparecen practicamente de inmediato, sin embargo los problemas pueden aparecer si el arbol tiene ingentes cantidades de datos, esto podria retrasar considerablemente la renderizacion del arbol y de la aplicacion en general y justamente este problema sera atacado en el ultimo articulo de la serie, prontamente.

Saludos

Un arbol con jsTree y ASP.NET MVC (I) – Instalacion

Hace ya bastante tiempo que vengo trabajando con ASP.NET MVC y jQuery y una de las necesidades que tuve fue la de mostrar una estructura jerarquica como un arbol. En ASP.NET Webforms lo teniamos un poco mas simple porque el framework incorpora un componente Tree, pero como no estamos con WebForms y prometimos no mirar atras, tuve que buscar una alternativa jQuery que me permita hacer lo que busco y aunque existen varias alternativas, algunas por el lado de google, que no necesariamente son jQuery-friendly, me fui por jsTree.

Dejenme decir que este plugin es uno que no tiene una buena documentacion, tiene poco mantenimiento y esta bastante “alejado” del camino que tomo jQuery hace unos anios, pero aun asi decidi usarlo por su excelente performance y por darme excelentes resultados de satisfaccion con el cliente y practicamente cero reclamos con relacion a sus capacidades.

Bueno aqui les doy los pasos que debemos seguir para configurarlo, la descarga la pueden realizar desde esta pagina, y aunque el archivo que descargues tiene instrucciones de instalacion, estas son parcas o escuetas, entonces yo recomiendo instalar de la siguiente manera:

Los elementos mas importantes en la instalacion son estos dos que estan marcados

image

En el proyecto de ASP.NET MVC deben insertar los archivos en la siguiente estructura:

image

Aqui pueden empezar las observaciones, porque desde todo punto de vista el colocar imagenes y temas en la carpeta de scripts deja mucho que desear, pero este setup es el setup por defecto, para evitar hacer esto deberiamos hacer una modificacion en el archivo .js, pero eso va tambien en contra de lo que quisiera hacer, asi que en aras de mantener la simplicidad no modifiquemos nada y coloquemos los archivos como les sugiero (por ahora)

Finalmente en el archivo _Layout.cshtml, que hace las veces de “MasterPage” colocamos la siguiente linea:

image

Con todo esto ya tenemos listo el plugin de jsTree para ser utilizado.

En el siguiente articulo muestro como utilizarlo para mostrar datos en el arbol.

Un saludo

Notas sobre instaladores

 

 

Me he visto en la necesidad de investigar un poco mas acerca de instaladores y todo el mundo complejo que involucra, aqui algunas de mis anotaciones mas importantes: 

Herramientas de Monitoreo de Instalacion/Desinstalacion 

 

  • Herramienta gratuita monitoreo de cambios en el disco duro y en el registro de windows: Spyme Tools (http://www.lcibrossolutions.com/spyme_tools.htm) Yo la utilice y sirve bastante sin embargo puede llegar a tener mucha informacion a revisar. 
  • Pagina que contiene diversas herramientas de monitoreo de cambios en el sistema, algunas ya no existen pero vale la pena revisarla: http://www.installsite.org/pages/en/tt_analyze.htm 
  • Herramienta comercial de desinstalacion. Su tecnologia Intalltracker es interesante, lo bueno de esta herramienta es que al momento de finalizar la desinstalacion reporta si han quedado cosas por quitar o remover, esto es muy util cuando se hace el desarrollo de los instaladores. Uninstall Tool 3 (http://www.crystalidea.com/uninstall-tool) 
  • Herramienta gratuita de desinstalacion ZSoft Unistaller, no la probe pero he escuchado buenos comentarios y tambien pueden ver que ha ganado varios premios: http://www.zsoft.dk/index/software 
  • Se acuerdan de regmon y filemon, pues Process Monitor es el que los combina a ambos y no es malo decir que he visto un par de hacktivistas usar esta herramienta para hacer de las suyas 🙂 http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx 

 

 

Herramientas de construccion de instaladores 

 

  • El proyecto de Deployment de Visual Studio, es simple y para instaladores que no hacen cosas «complejas» anda bien 
  • Wix, definitivamente la mas versatil de las herramientas, permite tener un control total de la base de datos MSI 🙂 y encima es software libre y tiene muchas personas que ya la usan.  
  • Installshield, el menos querido de mis recomendaciones, tiene caracteristicas interesantes, lo malo es que anda medio que liado con su Installscript un «lenguaje de programacion script» que es algo asi como un hibrido entre C, VB y pascal. 

 

Sitios Web 

 

  • Installsite.org, un sitio que reune mucha informacion acerca de los instaladores, esta comprometido con Installshield, lo que en algunos articulos lo hace muy parcializado. 

 

 

Libros 

 

  • Nuevamente Wix tiene mi mayor atencion, aquí el libro que recomiendo por su relacion con esa tecnologia y por ser tambien el mas reciente (2010): WiX- A Developer’s Guide to Windows Installer XML (en proceso de lectura…) 
  • Una guia mas general acerca de MSI, algo antiguo (2004) pero aun recomendado por algunos amigos: The Definitive Guide to Windows Installer  
  • Un libro vinculado a Installshield, mas antiguo que el resto (2002): Getting Started with InstallShield Developer and Windows Installer Setups  
  • Finalmente un conjunto de manuales a descargar del sitio de Flexera – Installshield son de la version 2010 (y bueno me toco esa version y luego migrar a Wix), el mas importante de esos manuales es: InstallShield 2010 InstallScript Language Reference Guide  

 

 

 

 

Como detectar internet en aplicaciones Windows y Web

Hoy en dia podemos concebir nuestra vida sin internet? Yo creo que no. Las aplicaciones que escribimos mas y mas asumen que estaremos conectados continuamente a Internet. Pero hay escenarios donde aun no podemos garantizar una conexion permanente a Internet: zonas rurales o caidas de la infraestructura de red de nuestro proveedor. En paises como el mio tambien el no tener internet puede considerarse bastante comun. En cualquier caso determinar si estoy conectado a internet es practicamente un requisito implicito para las aplicaciones que escribimos hoy y en muchos foros y listas de discusion se pregunta lo mismo y hay varias respuestas. Pero aqui les mostrare la respuesta oficial de Microsoft y mi propia implementacion Smile

La idea y el gran “secreto” es usar el NCSI de Microsoft (Network Connectivity Status Indicator) tal como se explica en este articulo.

En el articulo encontraran que la parte mas importante es esta (al menos para mi):

Type of Request that NCSI Sends What NCSI Expects to Receives if Connectivity Exists
A request for http://www.msftncsi.com/ncsi.txt

Page called ncsi.txt containing the following line of text with no terminating new line or other non-printing characters:

Microsoft NCSI

(Page headers disable caching.)

A request for DNS name resolution ofdns.msftncsi.com

Resolution of the DNS name to: 131.107.255.255

Bueno aqui mi implementacion, agregando una validacion adicional, que el/los adaptadores de red esten habilitados, probablemente es redundante pero….

1 public bool IsInternetConnected() 2 { 3 //Stopwatch clock = new Stopwatch(); 4 //clock.Start(); 5 6 var isNetworkAvailable = IsNetworkAvailable(); 7 if (!isNetworkAvailable) return false; 8 var ncsiRequest = IsNCSIConnected(); 9 var dnsLookupNCSIResolved = IsDnsLookupResolved(); 10 11 //clock.Stop(); 12 //Debug.WriteLine("Time elapsed " + clock.ElapsedMilliseconds + " milliseconds"); 13 //Console.WriteLine("Time elapsed " + clock.ElapsedMilliseconds + " milliseconds"); 14 //Debug.WriteLine("Time elapsed " + clock.ElapsedMilliseconds / 1000 + " seconds"); 15 //Console.WriteLine("Time elapsed " + clock.ElapsedMilliseconds / 1000 + " seconds"); 16 if (ncsiRequest || (!ncsiRequest && dnsLookupNCSIResolved)) return true; 17 return false; 18 }

El codigo comentado lo dejo ahi porque yo lo use para hacer mediciones de tiempos y tambien por si en algun momento ustedes necesitan hacerlas.

1 private bool IsNetworkAvailable(long minimumSpeed=0) 2 { 3 if (!NetworkInterface.GetIsNetworkAvailable()) 4 return false; 5 6 foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces()) 7 { 8 // se descartan los elementos por razones estandar 9 if ((ni.OperationalStatus != OperationalStatus.Up) || 10 (ni.NetworkInterfaceType == NetworkInterfaceType.Loopback) || 11 (ni.NetworkInterfaceType == NetworkInterfaceType.Tunnel)) 12 continue; 13 14 // Se filtran modems, puertos seriales y cosas por el estilo 15 // se utiliza 10000000 como un minimo de velocidad para la mayoria de los casos 16 if (ni.Speed < minimumSpeed) 17 continue; 18 19 // Se descarta nic virtuales (vmware, virtual box, virtual pc, etc.) 20 if ((ni.Description.IndexOf("virtual", StringComparison.OrdinalIgnoreCase) >= 0) || 21 (ni.Name.IndexOf("virtual", StringComparison.OrdinalIgnoreCase) >= 0)) 22 continue; 23 24 return true; 25 } 26 return false; 27 }

El metodo parece demasiado rebuscado pero tiene excelentes consideraciones.

1 public bool IsNCSIConnected() 2 { 3 try 4 { 5 HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.msftncsi.com/ncsi.txt"); 6 HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 7 return response.StatusCode == HttpStatusCode.OK; 8 } 9 catch (Exception) 10 { 11 return false; 12 } 13 }

El metodo valida que se haya obtenido un codigo 200 como respuesta, no recupero el contenido del archivo consultado.

Finalmente verifico que se este resolviendo correctamente el DNS, todo para seguir el algoritmo propuesto por Microsoft.

Espero que les sea de utilidad, en una siguiente entrada mostrare el metodo de detectar internet pero en Windows Phone.

Saludos.

Una estrella en xaml

Esta es una entrada ridiculamente simple y se debe a una necesidad propia y a multiples preguntas que me hicieron, solo es el codigo para una estrella en XAML, la utilice para el control de rating, en mi proxima aplicacion de Windows Phone:

1 <Canvas x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> 2 <Path x:Name="star" 3 Canvas.Left="120" 4 Canvas.Top="120" 5 Stretch="Fill" 6 StrokeThickness="0" 7 StrokeLineJoin="Round" 8 Stroke="Yellow" 9 Fill="Yellow" 10 Width="30" 11 Height="30" 12 Data="F1 M 24,10.2671L 15.26,10.2048L 12.5,1.91182L 9.74,10.2048L 1,10.2671L 8.03423,15.4546L 5.39261,23.7861L 12.5,18.6992L 19.6074,23.7861L 16.9658,15.4546L 24,10.2671 Z "/> 13 </Canvas>

estrella

Saludos

Usando Git & GitHub & Nodester

Sabian que Codeplex ahora soporta Git como DVCS? (https://www.infoworld.com/d/application-development/microsoft-adds-git-support-codeplex-repository-189372?source=rss_application_development) Este chisme me sirve como introduccion a lo que les voy a contar. Hace algunas semanas unos amigos me pidieron ayudar en un proyecto que involucra Node.js, el porque Node.js y no ASP.NET va ma alla de este simple post, aunque en realidad si usaremos ASP.NET en combinacion con Node.js, pero esa es otra historia. Entonces acepte la idea y tome el desafio, con mi conocimiento escencial de javascript & coffeescript emprendimos un par de semanas de arduo trabajo nocturno, pues mi trabajo “normal” me consume la mayor parte del dia y las clases que doy en la universidad un par de horas de la noche, como se imaginaran casi no me quedo tiempo de dedicarlo a mi familia y a dormir, al menos ese par de semanas fue una locura. Pero todo fue excelente pues aunque el proyecto no es la gran cosa “no podemos decir exactamente que es por acuerdos de confidencialidad” para mi fue una oportunidad de aprender nuevas tecnologias y eso hice y aqui, en este espacio, les voy presentando algunas de las aventuras que vivi.

La aplicacion Node.js no es el tema que me trae precisamente a este punto, la aplicacion la programamos en un servidor local y mi aventura comienza cuando debemos encontrar un hosting para la aplicacion, afortunadamente escucho de Nodester que ofrece un servicio gratuito precisamente para Node.js, la unica cosilla que novedosa…. es que usa Git para controlar los cambios en los archivos.

Git es un software de control de versiones, digamos al mejor estilo de comparacion con SVN, Mercurial, etc. (No lo comparo con TFS porque aunque se podria decir que TFS tiene un control de versiones, TFS es mucho mas que solo un VCS). Pero tambien Git tiene sus bondades y es que hace tiempo anduve buscando un VCS que me permita hacer un rastreo de los cambios de mis archivos de modo local, es decir sin tener que instalar un servidor de TFS o un servidor de SVN …. bueno uds me entienden y efectivamente Git permite eso, ademas que trae un interesante concepto llamado Social Coding que va mas alla del Open Source. El concepto, la filosofia y las herramientas de Git me encantaron, despertaron mi interes mas alla de Nodester Smile entonces decidi instalarlo, configurarlo y utilizarlo.

Aqui algunos pasos que segui y algunas de mis recomendaciones para los que tambien se inician:

El libro de referencia perfecta para Git es “Git Pro” de Scott Chacon: http://progit.org/book/, recomiendo leer al menos los primeros 3 capitulos, el libro es genial

  1. Afortunadamente Nodester me paso un excelente punto de inicio. Yo usuario de Windows no pienso resignar mi Sistema Operativo asi que empece por aqui: http://help.github.com/win-set-up-git/, que es la guia oficial de Github para instalar Git bajo Windows, genial
  2. La recomendacion que les hago al seguir la guia es, hacerlo exactamente con los pasos tal cual les dicen, de lo contrario estaran viendose a ustedes mismos bloqueados en algun punto de la configuracion.
  3. La generacion de las llaves puede resultar un poco truculenta Smile pero una vez que lo hagan todo funciona bien. Truculenta en el sentido de que si se equivocan en algo por ejemplo en el directorio donde generan las llaves puede ser que la conexion con Github o Nodester, no funcionara!
  4. Luego a instalar la app de nodester usando “npm install nodester-cli -g ”
  5. Hacer un setup de las cuentas de Nodester
  6. Finalmente seguir las instrucciones del video http://www.youtube.com/watch?v=jwsP1Ejv-_w hay algunas cosas que no me funcionaron al seguir esas instrucciones, ya lo reporte y seguramente haran un update de sus herramientas o en el peor de los casos del video Smile

Pero las cosas no quedaron ahi, yo me adentre mas al mundo de Git y comence a usar Github, se que hay otras muchas opciones pero bueno seguramente en algun momento las probare.

  • Descargue e instale un conjunto de herramientas llamadas GitExtensions, que tienen varias utilidades entre ellas un plugin para VS2010, de tal forma de integrar Git dentro de VS, debo decir que no le llega ni a los talones a TFS Smile pero tampoco lo necesita porque todo puede hacerse desde la la linea de comandos llamada Git Bash, que es absolutamente genial.
  • El siguiente paso es subir un proyecto a Github y las instrucciones para crear y “promover” cambios a un repositorio en Github estan aqui: http://help.github.com/create-a-repo/
  • El comando “git remote add origin git@github.com:username/Hello-World.git” es el “secreto” de todo, pero aunque las instrucciones son simples y hay documentacion por todo lado, un serio problema me mantuvo bloqueado un par de horas fue un error que decia “Disconnected: No supported authentication methods available”
  • La causa del error… la falta de un archivo .profile en el /home, el archivo tenia que contener la ruta al ejecutable ssh.exe, el contenido del archivo a continuacion:

SSH_ENV=»$HOME/.ssh/environment»
GIT_SSH=»/usr/bin/ssh.exe»

Luego de agregar este archivo todo funciono de maravillas a tal punto que ya subi un proyecto a github, justamente el proyecto de mi anterior post Objetos Globales con CoffeeScript / Javascript, lo pueden encontrar aqui: https://github.com/tecnocrata/GlobalObjectsCoffeeScript

Bueno eso es todo por ahora.

Saludos

Objetos Globales con CoffeeScript / Javascript

Antes que nada debo indicar que no soy un experto en Javascript y mucho de lo que escribire a continuacion puede sonar conocido, repetitivo y tonto para algunos, sepan disculparme. Bueno, por aquella complejidad intrinseca de Javascript es que yo he encontrado fabuloso el concepto de CoffeeScript y ultimamente estoy involucrandome bastante con Node.js lo que me lleva a tener que prepararme mas aun en javascript y este post contiene la respuesta a una de mis grandes preguntas: Como puedo estructurar objetos globales usando Javascript+CoffeeScript+jQuery+ASP.NET MVC? y todo esto de manera orientada a objetos ….uff para los que no conozcan estas tecnologias puede sonar mas complejo de lo que en realidad es. Encontre tres soluciones que se las presento a continuacion.

Primeramente mostrarles el contenido resumido del archivo index.cshtml, que basicamente contiene un boton y codigo jQuery, para capturar el evento click:

1 @{ 2 ViewBag.Title = "Home Page"; 3 } 4 5 <h2>@ViewBag.Message</h2> 6 <p> 7 To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>. 8 <br/> 9 <input type="button" id="btnDemo" value="Click me!"/> 10 </p> 11 12 <script type="text/javascript"> 13 14 $("#btnDemo").click(function () { 15 //Code here... 16 }); 17 </script>

El contenido relevante del archivo _Layout.cshtml es el siguiente:

1 <head> 2 <title>@ViewBag.Title</title> 3 <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" /> 4 <script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script> 5 <script src="@Url.Content("~/Scripts/tx/common1.js")" type="text/javascript"></script> 6 <script src="@Url.Content("~/Scripts/tx/common2.js")" type="text/javascript"></script> 7 <script src="@Url.Content("~/Scripts/tx/common3.js")" type="text/javascript"></script> 8 </head>

 

Solucion 1

Mi archivo common1.coffee es el siguiente, el “secreto” en esta solucion es el caracter de arroba (@) colocado por delante del nombre de la clase, esto “magicamente” logra el efecto de crear la clase GlobalMessage1 y asignarla al objeto this que gracias al closure de coffeescript es window, es decir aqui this == window.

1 class @GlobalMessage1 2 say_hello: () -> 3 alert "Hello Method 1" 4 5 class PrivateMessage1 6 say_nothing: ()-> 7 alert 'Nothing'

He utilizado una clase adicional llamada PrivateMessage1 para que puedan ver la diferencia con GlobalMessage1 al momento en que se genera el archivo javascript common1.js.

1 <script type="text/javascript"> 2 3 $("#btnDemo").click(function () { 4 var gm = new GlobalMessage1(); 5 gm.say_hello(); 6 }); 7 </script>

Solucion 2

En esta solucion la idea es preparar las clases para estar dentro de namespaces, ficticios porque javascript no soporta el concepto de namespace. Pero gracias al “truco” utilizado, estoy simulando uno. Debo indicar que no considero recomendable tener mas de dos niveles en el namespace del framework que armen, basicamente porque resultaria bastante complicado e ilegible ir escribiendo todos los niveles, a continuacion el contenido del archivo common2.coffee:

1 window['Framework1'] = {} 2 #window['Framework1.Utilities'] = {} 3 window['Framework1.GlobalMessage'] = {} 4 5 class Framework1.GlobalMessage 6 say_hello: () -> 7 alert "Hello Method 2"

El contenido del archivo index.cshtml es el siguiente:

1 <script type="text/javascript"> 2 3 $("#btnDemo").click(function () { 4 var gm = new Framework1.GlobalMessage(); 5 gm.say_hello(); 6 }); 7 </script>

Solucion 3

Finalmente, encontre una solucion “mas adecuada” y que segun lo que lei es la que debe usarse cuando se utiliza Node.js, entonces aqui tenemos el codigo del archivo common3.coffee:

1 root = exports ? this 2 root.Framework2 = 3 Utilities: {} 4 GlobalMessage: {} 5 6 class Framework2.GlobalMessage 7 say_hello: () -> 8 alert "Hello Method 3"

El contenido de archivo index.cshtml, es el siguiente:

1 <script type="text/javascript"> 2 3 $("#btnDemo").click(function () { 4 var gm = new Framework2.GlobalMessage(); 5 gm.say_hello(); 6 }); 7 </script>

Si alguno tiene algun comentario u observacion a este codigo es mas que bienvenido, muchas gracias.

Aqui el archivo comprimido de la solucion: