<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Programando por diversion</title>
	<atom:link href="http://copstone.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://copstone.com</link>
	<description>La programacion es la pieza angular de cualquier software</description>
	<lastBuildDate>Fri, 13 Jan 2012 15:01:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Trabajando con Word en Visual Studio 2010 y C#</title>
		<link>http://copstone.com/2012/01/trabajando-con-word-en-visual-studio-2010-y-c/</link>
		<comments>http://copstone.com/2012/01/trabajando-con-word-en-visual-studio-2010-y-c/#comments</comments>
		<pubDate>Tue, 10 Jan 2012 19:38:42 +0000</pubDate>
		<dc:creator>Victor Parasi</dc:creator>
				<category><![CDATA[Productividad]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Word]]></category>

		<guid isPermaLink="false">http://copstone.com/?p=1175</guid>
		<description><![CDATA[Este post esta hecho para explicar como buscar y reemplazar e insertar tablas en Word mediante Visual Studio y C#]]></description>
			<content:encoded><![CDATA[<p>Este post es una extensión de uno que ya tiene algo de tiempo, pero lo hice porque me pidieron ayuda en explicar como se hacen algunas cosas. No voy a explicar como interactuar con el documento Word, eso esta en el post <a href="http://copstone.com/2010/05/crear-un-documento-msword-con-c-sharp/">anterior</a>, lo que voy a hacer es presentar dos casos puntuales de automatización.</p>
<h2>Búsqueda y Reemplazo de Palabras.</h2>
<p>Imaginemos que tenemos un documento y queremos reemplazar una palabra por otra.</p>
<p>Para ubicarte en la forma que he trabajado, les comento que he definido un proyecto del tipo ClassLibrary y allí he colocado los métodos necesarios.</p>
<p>&nbsp;</p>
<pre class="brush:csharp;auto-links:false;collapse:false;first-line:1;gutter:true;smart-tabs:true;wrap-lines:true;%SYNTAX_HIGHLIGHTER_CSHARP%">public class WordCsharp
    {

        Word.Application _objWordApplication; //Objeto Word
        Word.Document _objWordDocument;  //Objeto Document
        Object oMissing = System.Reflection.Missing.Value;

	//Funcion que sirve para abrir un archivo de Word creado previamente.
        private void LoadWordFile(string _filename)
        {
            _objWordApplication = new Word.Application();
            _objWordDocument = _objWordApplication.Documents.Open(_filename,false,false,false,
				ref oMissing, ref oMissing,
				ref oMissing, ref oMissing);
            _objWordApplication.Visible = true;
        }

	//Funcion que Busca y reemplaza un texto por otro.
        public void FindReplace(string _filename, string _find, string _replace)
        {
            	//Abrimos el archivo
		LoadWordFile(_filename);
		//Seleccionamos todo el documento para buscar y reemplazar el texto
                Word.Find findObject = _objWordApplication.Selection.Find;
                findObject.ClearFormatting();
                findObject.Text = _find;
                findObject.Replacement.ClearFormatting();
                findObject.Replacement.Text = _replace;

                //Escoger esta opción permite reemplzar todas las
		//ocurrencias del texto en el documento.
		object replaceAll = Word.WdReplace.wdReplaceAll;
                findObject.Execute(ref oMissing, ref oMissing,
				   ref oMissing, ref oMissing, ref oMissing,
                                   ref oMissing, ref oMissing, ref oMissing,
				   ref oMissing, ref oMissing, ref replaceAll,
				   ref oMissing, ref oMissing, ref oMissing,
				   ref oMissing);
            }

        }
    }</pre>
<p>&nbsp;</p>
<h2>Insertando una Tabla</h2>
<p>Continuando con la misma clase anterior, ahora vamos a crear un método que inserte, al final del documento, una tabla. La dimensión de la tabla la puedes pasar como parámetro.</p>
<pre class="brush:csharp;auto-links:false;collapse:false;first-line:1;gutter:true;smart-tabs:true;wrap-lines:true;%SYNTAX_HIGHLIGHTER_CSHARP%">public void InsertTable(string _filename,int _col, int _row)
        {

            //Abrimos el archivo
            LoadWordFile(_filename);
            //Bookmark de final del archivo
	    Object end_document="\\endofdoc";
	    //Definimos la tabla
            Word.Table _table;
            Word.Range wrdRng = _objWordDocument.Bookmarks.get_Item(ref end_document).Range;
            _table = _objWordDocument.Tables.Add(wrdRng, _row, _col,
					ref oMissing, ref oMissing);
            _table.Range.ParagraphFormat.SpaceAfter = 6;
            int r, c;
            string strText;
            for (r = 1; r &lt;= _row; r++)
                for (c = 1; c &lt;= _col; c++)
                {
		    //Este es el texto que vamos a colocar en cada Celda
                    strText = "r" + r + "c" + c;
                    _table.Cell(r, c).Range.Text = strText;
                }
            //Cambiando los items de la primera fila
            _table.Rows[1].Range.Font.Bold = 1;
            _table.Rows[1].Range.Font.Italic = 1;
            //Visualizando los bordes Verticales y Horizontales
            _table.Borders[Word.WdBorderType.wdBorderVertical].Visible=true ;
            _table.Borders[Word.WdBorderType.wdBorderHorizontal].Visible = true; 

        }</pre>
<p>Observa con cuidado que en el método anterior se abre el documento nuevamente. Esa línea la puedes quitar si es que sobre UN solo documento se va a aplicar varias opciones.</p>
<p>&nbsp;</p>
<p>Espero que le saquen provecho a este post automatizando cada vez mas cosas en Word.</p>
]]></content:encoded>
			<wfw:commentRss>http://copstone.com/2012/01/trabajando-con-word-en-visual-studio-2010-y-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ASP.NET y MVC 3&#8211;Parte I</title>
		<link>http://copstone.com/2012/01/asp-net-y-mvc-3parte-i/</link>
		<comments>http://copstone.com/2012/01/asp-net-y-mvc-3parte-i/#comments</comments>
		<pubDate>Wed, 04 Jan 2012 14:00:00 +0000</pubDate>
		<dc:creator>Victor Parasi</dc:creator>
				<category><![CDATA[Productividad]]></category>
		<category><![CDATA[MVC]]></category>

		<guid isPermaLink="false">http://copstone.com/?p=1165</guid>
		<description><![CDATA[Luego de describir el patrón MVC, vamos a ponerlo en práctica con una aplicación Web. Vamos a analizar la interacción entre las vistas y el controlador para luego realizar algo más avanzado.]]></description>
			<content:encoded><![CDATA[<p><em><span style="color: #0000ff;">Antes de empezar, quisieramos dar gracias a los que nos escribieron para felicitarnos por haber escrito un post luego de mucho tiempo.  Debido a la confianza que les tenemos, les explicaremos brevemente el motivo de haber dejado de escribir. Cuando  decidimos crear el blog, lo hicimos, en primer lugar, para tener un canal de comunicación con todas las personas que, como a nosotros, les gusta programar. Escribir lo que sabemos o contar algunas investigaciones realizadas fue nuestra principal motivación.  Lastimosamente, no todo en la vida es color de rosa. Este blog , para nosotros, tiene un costo y habíamos pensado mantenerlo mediante la publicidad existente, pero a la fecha no ha tenido los resultados esperados, debido a eso nos vimos en la necesidad de dedicar nuestro tiempo en otras ocupaciones. </span></em></p>
<p><em><span style="color: #0000ff;">Luego de analizar la situación, hemos decidido empezar este 2012 con un ánimo renovado, borrando lo anterior y esperando que la fortuna nos acompañe y sobre todo que ustedes continuen leyendo y escribiendo sus comentarios  a los post que vamos a ir escribiendo.</span></em></p>
<p><em><span style="color: #0000ff;">Ahora si, los dejamos con el nuevo post, no sin antes darles gracias por su tiempo en leer estas líneas.</span></em></p>
<p><em><span style="color: #0000ff;">Atte.</span></em></p>
<p><em><span style="color: #0000ff;">Copstone….Programando por Diversión</span></em></p>
<p>En el post <a href="http://copstone.com/2012/01/model-view-controller/">anterior</a> vimos de que trataba el MVC. En este post vamos a analizar una aplicación Web sencilla  con ASP.NET y MVC 3. El concepto de  MVC 3 en ASP.NET hace referencia a un framework para que nuestras aplicaciones web sean desarrolladas bajo el patrón MVC. Lo puedes descargar desde este <a href="http://www.microsoft.com/download/en/details.aspx?displaylang=en&amp;id=1491">link</a>.</p>
<h2>Creación del Proyecto</h2>
<p>Luego de instalar los archivos, reinicia tu VS 2010 y crea un nuevo proyecto del tipo Web en el lenguaje C#. De manera específica vamos a realizar un proyecto del tipo ASP. NET MVC 3 Web Application.</p>
<p><a href="http://copstone.com/wp-content/uploads/2012/01/image1.png"><img style="background-image: none; margin: 15px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px; border-width: 0px;" title="image" src="http://copstone.com/wp-content/uploads/2012/01/image_thumb1.png" alt="image" width="506" height="312" border="0" /></a></p>
<p>Le voy a poner de nombre al proyecto <strong>DemoMVC3App </strong>y luego pulsar el botón <strong>OK</strong></p>
<p>Luego de pulsar el botón, vamos a acceder a una nueva ventana. En esta ventana vamos a escoger el motor de vistas que usaremos y el template del proyecto que usaremos.</p>
<ul>
<li>Para el Motor de Vistas (View Engine) escogeremos <strong>RAZOR</strong>. Este motor permite un acceso mejorado a las vistas que las del motor ASPX. Este es uno de los cambios del MVC 3 con respecto a sus predecesores.</li>
<li>En el caso de los template, usaremos el template que permite la creación de una “project with an account controller that uses forms authentication.”</li>
</ul>
<p>&nbsp;</p>
<p><a href="http://copstone.com/wp-content/uploads/2012/01/image2.png"><img style="background-image: none; margin: 15px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px; border-width: 0px;" title="image" src="http://copstone.com/wp-content/uploads/2012/01/image_thumb2.png" alt="image" width="403" height="368" border="0" /></a></p>
<p>Luego de presionar OK, esperamos unos segundos y se crea el proyecto de la siguiente forma:</p>
<p><a href="http://copstone.com/wp-content/uploads/2012/01/image3.png"><img style="background-image: none; margin: 15px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px; border-width: 0px;" title="image" src="http://copstone.com/wp-content/uploads/2012/01/image_thumb3.png" alt="image" width="600" height="325" border="0" /></a></p>
<p>Como pueden ver, en el Solution Explorer, se han creado carpetas y llaman la atención 3 de ellas, Controllers, Models y Views.</p>
<h2>Vistas</h2>
<p>Como ya saben, las vistas vienen a ser las interfaces que van a visualizar el usuario. Si ejecutan la aplicación, tal como está, verán la siguiente página inicial:</p>
<p><a href="http://copstone.com/wp-content/uploads/2012/01/image4.png"><img style="background-image: none; margin: 15px 0px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://copstone.com/wp-content/uploads/2012/01/image_thumb4.png" alt="image" width="600" height="325" border="0" /></a></p>
<p>Si analizamos la interacción del usuario con la página tenemos:</p>
<ul>
<li>Puede dar Click en HOME</li>
<li>Puede dar Click en About</li>
<li>Puede dar Click en LogOn</li>
</ul>
<p>Estas tres interacciones, según el concepto de MVC, deberían generar, cada una,  un evento el cual debe de ser controlado por un Controller y llevar a la visualización de vistas, digamos 3 vistas. Veamos si esto es cierto.</p>
<p>Vamos a VS2010, en la carpeta Views, veamos que hay dentro de esa carpeta.</p>
<p><a href="http://copstone.com/wp-content/uploads/2012/01/image5.png"><img style="background-image: none; margin: 15px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px; border-width: 0px;" title="image" src="http://copstone.com/wp-content/uploads/2012/01/image_thumb5.png" alt="image" width="232" height="316" border="0" /></a></p>
<p>Si expandimos la carpeta View, vemos que existe una subcarpeta Account, con varios archivos, pero nos interesa por ahora LogOn.cshtml. También vemos una carpeta llamada Home con dos archivos About.cshtml e Index.cshtml.</p>
<p>A estas alturas ya deben de haber deducido algo, y si no se los digo. Los archivos mencionados, son las <strong>vistas </strong>de las 3 opciones que mencionamos líneas arribas. Para despejar las dudas, los invito a abrir esos archivos y verán que el contenido de los mismos son tag o controles que se visualizan al momento de dar click en cada una de las opciones.</p>
<p>Una pregunta se cae de madura y si no te la haces, la hago yo. Se dieron cuenta que los archivos tienen extensión CSHTML?, la respuesta es el motor de vistas seleccionado RAZOR.</p>
<h2>Controladores</h2>
<p>Nuevamente recordemos el concepto de MVC. El controlador intercepta los eventos y dependiendo de lo que se desee realizar interactúa, finalmente, con una vista para visualizar algo.</p>
<p>Veamos el contenido de la carpeta Controllers del proyecto.</p>
<p><a href="http://copstone.com/wp-content/uploads/2012/01/image6.png"><img style="background-image: none; margin: 15px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px; border-width: 0px;" title="image" src="http://copstone.com/wp-content/uploads/2012/01/image_thumb6.png" alt="image" width="280" height="321" border="0" /></a></p>
<p>Contiene dos archivos, uno llamado AccountController.cs y otro llamado HomeController.cs.</p>
<p>Para que tenga sentido estos nombres recordemos que en la carpeta Views encontramos dos subcarpetas. Una llamada Account y otra llamada Home. Por lo tanto AccountController es el controlador de las vistas de la carpeta Account y HomeController el controlador de las vistas que se encuentran la carpeta Home.</p>
<p>Ahora, vamos a ver el contenido de un Controlador. Veamos el archivo HomeController.cs</p>
<pre class="brush:csharp;auto-links:false;collapse:false;first-line:1;gutter:true;smart-tabs:true;wrap-lines:true;%SYNTAX_HIGHLIGHTER_CSHARP%">using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace DemoMVC3App.Controllers
{
    public class HomeController : Controller
    {
	//Esta método se invoca cuando el usuario da click en la opción HOME.
	//La página de HOME es la página de inicio de la aplicación
        //Para que quede claro diremos que si el website esta en localhost,
	//esta página se visualiza si colocamos en el browser
	//http://localhost o http://localhost:1239/Home/ en la barra de direcciones

	public ActionResult Index()
        {
            ViewBag.Message = "Welcome to ASP.NET MVC!";

            return View();
        }

	//Esta método se invoca cuando el usuario da click en la opción ABOUT.
        //Para que quede claro diremos que si el website esta en localhost
	//Si colocamos en el browser http://localhost:1239/Home/About

        public ActionResult About()
        {
            return View();
        }
    }
}</pre>
<p>En este punto y ya casi para terminar este post, debemos de dejar en claro como funciona la vista y el controlador.</p>
<ul>
<li>Si en la carpeta Views existe una subcarpeta llamada Home (que agrupa a muchas vistas) en la carpeta Controllers debe de haber un archivo llamado HomeController que será el controlador de las vistas.</li>
<li>Si dentro de la subcarpeta Home, que hay en Views, existe un archivo llamado Index.cshtml, en el archivo HomeController debe de haber un método <strong>public ActionResult Index()</strong>.</li>
</ul>
<p>En el siguiente post, vamos a agregar vistas y trabajar con el controlador para que veas lo sencillo que es.</p>
]]></content:encoded>
			<wfw:commentRss>http://copstone.com/2012/01/asp-net-y-mvc-3parte-i/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Model View Controller</title>
		<link>http://copstone.com/2012/01/model-view-controller/</link>
		<comments>http://copstone.com/2012/01/model-view-controller/#comments</comments>
		<pubDate>Mon, 02 Jan 2012 15:08:00 +0000</pubDate>
		<dc:creator>Victor Parasi</dc:creator>
				<category><![CDATA[Productividad]]></category>
		<category><![CDATA[MVC]]></category>

		<guid isPermaLink="false">http://copstone.com/?p=1110</guid>
		<description><![CDATA[El modelo Model-View-Controller (MVC) es un patrón de diseño arquitectónico que separa los componentes de una aplicación. Esta separación ofrece más control sobre las partes individuales de la aplicación, lo cual permite desarrollarlas, modificarlas y probarlas más fácilmente.]]></description>
			<content:encoded><![CDATA[<p>El Model View Controller o comunmente conocido como MVC es un patrón de arquitectura de software que consiste en separar, en tres componentes disitintos, los datos, la interfaz y la lógica del negocio de una aplicación.</p>
<p>Este tipo de patrón, es común en aplicaciones del tipo Web, donde claramente se puede ver que la interfaz es el código HTML. Otra aplicación , más moderna, de este patrón es en el desarrollo de aplicaciones Móviles.</p>
<p>Si regresamos por un momento al nombre de este post, vamos a notar que esta compuesto por tres palabras Modelo, Vista y Controlador. Aprender estos tres conceptos son, entonces, de suma importancia para aprender como trabaja el patrón.</p>
<p>&nbsp;</p>
<ul>
<li>
<div align="justify"><strong>Modelo</strong>: Esta conformado por los datos que forman parte de la aplicación, engloba los métodos necesarios para acceder (lógica) y manipular los datos.  El modelo debe de ser fácil de entender, y capaz de soportar a la mayor variedad de clientes. Debe de tener una interfaz que permita exponer los métodos para acceder y actualizar el estado de los objetos y ejecutar procesos complejos.  El modelo contiene servicios que son accedidos por el controlador, ya sea para consulta o efectuar algunos cambio de estado. El modelo debe notificar a la vista cuando exista algún cambio de estado.</div>
</li>
<li><strong>Vista</strong>: Se encarga de presentar, al cliente, el estado del modelo en un formato adecuado para interactuar. Usualmente es conocida como la interfaz de usuario. La semántica de la presentación se<br />
encapsulado dentro de la vista, por lo tanto los datos del modelo se puede adaptar para diferentes tipos de clientes. La vista debe de actualizarse cuando hay un cambio en el modelo.</li>
<li><strong>Controlador</strong>: Se encarga de responde a eventos, usualmente acciones del usuario, e invoca peticiones al modelo y, probablemente, a la vista. El controlador se encarga de seleccionar la siguiente vista basado en el usuario de entrada y el resultado de las operaciones del modelo.</li>
</ul>
<p>Veamos, gráficamente, la interacción entre estos tres componentes:</p>
<p><a href="http://copstone.com/wp-content/uploads/2012/01/image.png"><img style="background-image: none; margin: 15px auto; padding-left: 0px; padding-right: 0px; display: block; float: none; padding-top: 0px; border-width: 0px;" title="image" src="http://copstone.com/wp-content/uploads/2012/01/image_thumb.png" alt="image" width="445" height="275" border="0" /></a></p>
<p>&nbsp;</p>
<p>Para que quede claro el funcionamiento de MVC, analicemos el siguiente ejemplo:</p>
<p><strong>Caso:</strong> Imaginemos que hemos desarrollado una página de Registro de Datos. El usuario, luego de ingresar la informacion necesaria, pulsa el botón OK.  En ese momento, el uso de MVC en nuestra aplicación lleva a lo siguiente:</p>
<ol>
<li>El usuario interactúa con la interfaz de usuario, pulsando el botón OK ( o cualquier otro tipo de disparador).</li>
<li>El <strong>controlador</strong> recibe (por parte de los objetos de la <span style="color: #000000;"><strong>vista</strong></span>) la notificación de la acción solicitada por el usuario. El controlador gestiona el evento que llega, frecuentemente a través de un gestor de eventos (handler) o callback.</li>
<li>El <span style="color: #000000;"><strong>controlador</strong></span> accede al <strong>modelo</strong>, actualizándolo, posiblemente modificándolo de forma adecuada a la acción solicitada por el usuario.</li>
<li>El <strong>controlador</strong> delega a los objetos de la <strong>vista</strong> la tarea de desplegar la interfaz de usuario. La <strong>vista</strong> obtiene sus datos del modelo para generar la interfaz apropiada para el usuario(según los permisos o roles que tenga)  donde se reflejan los cambios en el modelo. Durante la interacción el controlador no pasa objetos de dominio (el <strong>modelo</strong>) a la <strong>vista</strong> aunque puede dar la orden a la <strong>vista</strong> para que se actualice. <strong>Nota: </strong>En algunas implementaciones la vista no tiene acceso directo al modelo, dejando que el controlador envíe los datos del modelo a la vista.</li>
<li>La interfaz de usuario (<strong>vista</strong>) espera nuevas interacciones del usuario, comenzando el ciclo nuevamente.</li>
</ol>
<p>Espero que con este post quede claro lo que significa el modelo vista controlador, dado que lo voy a usar en un próximo post.</p>
]]></content:encoded>
			<wfw:commentRss>http://copstone.com/2012/01/model-view-controller/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>C&#243;mo crear una aplicaci&#243;n multihilos (multithread). AutoResetEvent vs. BackgroundWorker en Visual Studio 2008, C#</title>
		<link>http://copstone.com/2010/11/como-crear-una-aplicacin-multihilos-multithread-autoresetevent-vs-backgroundworker-en-visual-studio-2008-c/</link>
		<comments>http://copstone.com/2010/11/como-crear-una-aplicacin-multihilos-multithread-autoresetevent-vs-backgroundworker-en-visual-studio-2008-c/#comments</comments>
		<pubDate>Wed, 10 Nov 2010 16:45:33 +0000</pubDate>
		<dc:creator>Victor Parasi</dc:creator>
				<category><![CDATA[Productividad]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[thread]]></category>

		<guid isPermaLink="false">http://copstone.com/?p=1096</guid>
		<description><![CDATA[Los métodos mas conocidos para realizar tareas en segundo plano son la clase AutoResetEvent y el componente BackgroundWorker, pero ¿qué usar en cada caso? Sencillo, si lo que requieres es poner varias tareas en segundo plano pero es necesario que tu aplicación espere a que todas las tareas hayan terminado para continuar con el flujo entonces la opción es AutoresetEvent; por otro lado, si lo que se busca es poner procesos pesados en segundo plano y no es necesario esperar a que todos terminen al mismo tiempo entonces implementa BackgroundWorker, este último con la ventaja sobre AutoresetEvent, que puede tener acceso a la interfaz de usuario al termino de cada tarea.]]></description>
			<content:encoded><![CDATA[<p><b>Antes de empezar, queremos agradecer a Yared Castro, por colaborar en la realización de este interesante post.&#160; </b></p>
<p>Sin importar el lenguaje que utilices, lo importantes es que debes siempre saber que: Al ejecutar una aplicación, el sistema operativo (sea Winodws o Linux) inicia un proceso para la aplicación y le asigna una serie de recursos para poder ejecutarse.</p>
<p>Es sobre este proceso (o llamado también hilo principal de ejecución), es sobre el cual aparece la primera pantalla de nuestra aplicación y se &quot;cuelgan&quot; las demás pantallas para ejecutarse.</p>
<p>Indudablemente que, si tenemos una opción que trabaja con máquinas o servidores ubicados remotamente, la invocación, ejecución y visualización de la información puede demorar más de lo debido. Una forma para aminorar esto o al menos hacer que nuestra aplicación siga ejecutándose de forma normal, mientras se procesa una operación es usar hilos (thread en inglés)</p>
<p>Definamos a un thread, como una unidad (bloque de código) que es ejecutado para realizar una operación determinada que: demora más de lo planeado o se quiere hacer de forma paralela. En ambos caso lo que hace el Sistema Operativo es lanzar un subproceso del proceso principal, de forma que desde el hilo principal de ejecución se desprenden las demás invocaciones. Algunos ejemplos del uso de thread, tenemos:</p>
<ul>
<li>Descargas de imágenes </li>
<li>Invocaciones del servicio Web </li>
<li>Descargas y cargas de archivos (incluso para las aplicaciones punto a punto) </li>
<li>Cálculos locales complejos </li>
<li>Transacciones de base de datos </li>
<li>Acceso del disco local, dada su baja velocidad relativa al acceso a memoria </li>
</ul>
<p>Aunque hay varias formas de implementar thread en nuestras aplicaciones, este artículo va a enseñar sólo dos de ellas: <i>AutoResetEvent </i>y usando el componente <i>BackgroundWorker</i></p>
<h3><i>AutoResetEvent</i></h3>
<p>Notifica que se ha producido un evento a un subproceso en espera y permite que los subprocesos se comuniquen unos con otros mediante señalamientos. Un subproceso espera una señal mediante una llamada a <i>WaitOne</i> en el método que se esta procesando en el AutoResetEvent. Si AutoResetEvent se encuentra en el estado no señalado, el subproceso se bloquea en espera de que el subproceso que controla el recurso en ese momento indique que dicho recurso está disponible mediante una llamada a <i>Set</i>.</p>
<p>A diferencia de BackgroundWorker, no contempla eventos para reportar progreso de ejecución de los hilos (threads) y se debe considerar que los “try catch” van en cada método para el manejo de excepciones que es una diferencia mas con BackgroundWorker.</p>
<p><a href="http://copstone.com/wp-content/uploads/2010/11/clip_image0026.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image002[6]" border="0" alt="clip_image002[6]" src="http://copstone.com/wp-content/uploads/2010/11/clip_image0026_thumb.jpg" width="590" height="256" /></a></p>
<p>Figura 1. Sincronización de threads con AutoResetEvent</p>
<p>Es posible que cada hilo se vaya enterando de lo que hace uno anterior mediante los señalamientos que comento en el primer párrafo, sin embargo, para efectos demostrativos únicamente de este artículo se esta tomando en cuenta que se desea sincronizar las tareas y estar al tanto del momento en todas las que se pongan en el ThreadPool hayan terminado.</p>
<p>&#160;</p>
<pre class="brush:csharp;auto-links:false;collapse:false;first-line:1;gutter:true;smart-tabs:true;wrap-lines:true;%SYNTAX_HIGHLIGHTER_CSHARP%">//Incluir en nuestra clase:
using System.Threading;
.
.
.

//Se instancia la clase, en este caso son tres hilos los que se ilustran
autoEventos = new AutoResetEvent[]
{
  new AutoResetEvent(false),
  new AutoResetEvent(false),
  new AutoResetEvent(false)
};
.
.
.

        //Se pone la tarea pesada por hilo dentro de cada metodo
        void LanzaHilo1(object stateInfo)
        {
            for (int i = 0; i &lt; 300; i++)
            {
                System.Threading.Thread.Sleep(50); //simulando trabajo
            }
            _hilo1Completado = true;
            //Se libera recurso
            autoEventos[0].Set();
        }

        void LanzaHilo2(object stateInfo)
        {
            for (int a = 0; a &lt; 100; a++)
            {
                System.Threading.Thread.Sleep(50); //simulando trabajo
            }
            _hilo2Completado = true;
            //Se libera recurso
            autoEventos[1].Set();
        }
.
.
.
        //Se lanzan los hilos
        string LanzaHilosJuntos()
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(LanzaHilo1));
            ThreadPool.QueueUserWorkItem(new WaitCallback(LanzaHilo2));
            ThreadPool.QueueUserWorkItem(new WaitCallback(LanzaHilo3));

            WaitHandle.WaitAll(autoEventos);

            label1.ForeColor = Color.Blue;
            label2.ForeColor = Color.Blue;
            label3.ForeColor = Color.Blue;

            return &quot;Hilos terminados&quot;;
        }</pre>
<p><i>Nota</i>: En caso de implementar el código y que se presente un error del tipo “WaitAll For Multiple Handles on a <b>STA</b> Thread Is Not Supported”, existen dos posibles soluciones, la primera es en el program.cs de la aplicación cambiar el atributo [STAThread] por [MTAThread] y con esto indicamos que nuestra aplicación es multiprocesos; la otra solución es usar <i>ManualResetEvent</i> en vez de <i>AutoResetEvent</i>.</p>
<h3>BackgroundWorker</h3>
<p>El componente BackgroundWorker proporciona la capacidad de ejecutar operaciones que llevan mucho tiempo de forma asincrónica (&quot;en segundo plano&quot;), en un subproceso diferente del subproceso principal de la interfaz de usuario de la aplicación. Para utilizar BackgroundWorker, simplemente hay que indicarle el método de trabajo cuya ejecución en segundo plano lleva mucho tiempo y, a continuación, llamar al método <i>RunWorkerAsync</i> . <i>RunWorkerAsync</i> toma un parámetro object opcional, <u>que se utiliza para pasar argumentos al método de trabajo</u>. Este método de trabajo es el evento <i>DoWork</i> que la clase BackgroundWorker expone, es en donde se pone la carga de trabajo que tardará tanto tiempo. Cuando finaliza el método, BackgroundWorker avisa al subproceso que hace la llamada desencadenando el evento <i>RunWorkerComplete</i>, que puede contener los resultados de la operación y que es en donde podemos tener acceso a la interfaz de la aplicación.</p>
<p>Usando BackgroundWorker se recomienda el uso de excepciones sobre los parámetros que devuelve <i>DoWork</i> en los argumentos que se pasan a <i>RunWorkerComplete</i> mediante “e.Error” en vez de usar un “try catch” por cada llamada.</p>
<p><a href="http://copstone.com/wp-content/uploads/2010/11/clip_image0024.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image002[4]" border="0" alt="clip_image002[4]" src="http://copstone.com/wp-content/uploads/2010/11/clip_image0024_thumb.jpg" width="621" height="147" /></a></p>
<p>Figura 2. Realizando tareas en segundo plano con BackgroundWorker</p>
</p>
<p>Para conocer las mejores prácticas en el subprocesamiento administrado te recomiendo que visites: <a href="http://msdn.microsoft.com/es-es/library/1c9txz50(v=VS.80).aspx">http://msdn.microsoft.com/es-es/library/1c9txz50(v=VS.80).aspx</a></p>
<pre style="width: 626px; height: 797px" class="brush:csharp;auto-links:false;collapse:false;first-line:1;gutter:true;smart-tabs:true;wrap-lines:true;%SYNTAX_HIGHLIGHTER_CSHARP%">//Se inicializa el componente para cada hilo
BackgroundWorker _hilo1 = new BackgroundWorker();
_hilo1.DoWork += new DoWorkEventHandler(_hilo1_DoWork);
_hilo1.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_hilo1_RunWorkerCompleted);
_hilo1.ProgressChanged += new ProgressChangedEventHandler(_hilo1_ProgressChanged);

//Se manda llamar el metodo para ejecutar la tarea pesada
_hilo1.RunWorkerAsync();

BackgroundWorker _hilo2 = new BackgroundWorker();
_hilo2.DoWork += new DoWorkEventHandler(_hilo2_DoWork);
_hilo2.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_hilo2_RunWorkerCompleted);
_hilo2.ProgressChanged += new ProgressChangedEventHandler(_hilo2_ProgressChanged);

_hilo2.RunWorkerAsync();
.
.
.
        //Empieza el trabajo pesado
        void _hilo2_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker bw = sender as BackgroundWorker;
            for (int i = 0; i &lt; 100; i++)
            {
                System.Threading.Thread.Sleep(50); //simulando trabajo
                bw.WorkerReportsProgress = true;
                bw.ReportProgress(i);
            }
            e.Result = true;
        }

        //Se completa el trabajo pesado y ya se tiene acceso a la interfaz de usuario
        void _hilo2_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            lblProgresoTotal.Text = &quot;Hilo 2 completado&quot;;
            hilo2Completado = Convert.ToBoolean(e.Result);
            txtHilo2.Enabled = false;
            label2.ForeColor = Color.Blue;
            lblProgresoHilo2.ForeColor = Color.Blue;

            if (hilo1Completado &amp;&amp; hilo2Completado &amp;&amp; hilo3Completado)
                btnComienzaHilos.Enabled = true;
        }

        //Progreso del trabajo asignado en DoWork
        void _hilo2_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            lblProgresoHilo2.Text = e.ProgressPercentage.ToString() + &quot;%&quot;;
            txtHilo2.Text = txtHilo2.Text + e.ProgressPercentage.ToString() + Environment.NewLine;
        }</pre>
<p><b>Demo</b></p>
<p>En el código que se adjunta, se muestra de forma sencilla una manera de usar AutoResetEvent y BackgroundWorker así como la principal diferencia entre ambos. </p>
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="326">
<p><a href="http://copstone.com/wp-content/uploads/2010/11/clip_image0028.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image002[8]" border="0" alt="clip_image002[8]" src="http://copstone.com/wp-content/uploads/2010/11/clip_image0028_thumb.jpg" width="223" height="244" /></a></p>
<p>Figura 3. Usando BackgroundWorker (<a href="http://copstone.com/wp-content/uploads/dlls/threads/PruebasBackgroundWorker.zip">descargar</a>)</p>
</td>
<td valign="top" width="326">
<p><a href="http://copstone.com/wp-content/uploads/2010/11/clip_image004.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image004" border="0" alt="clip_image004" src="http://copstone.com/wp-content/uploads/2010/11/clip_image004_thumb.jpg" width="212" height="244" /></a></p>
<p>Figura 4. Usando AutoresetEvent(<a href="http://copstone.com/wp-content/uploads/dlls/threads/PruebasAutoResetEvent.zip">descargar</a>)</p>
</td>
</tr>
</tbody>
</table>
<p><b>Conclusión</b></p>
<p>Cuando se usa BackgroundWorker se tiene la flexibilidad de tener acceso a la interfaz de usuario desde RunWorkerCompleted una vez que se van completando las tareas en segundo plano.</p>
<p>AutoResetEvent es de gran ayuda cuando es necesario realizar varios procesos al mismo tiempo con la funcionalidad de sincronización de tareas para esperar el término de cada hilo y poder hacer uso del resultado de cada uno en un proceso posterior. </p>
<p>Ambos casos (AutoResetEvent y BackgroundWorker) ven en aumento su performance con las maquinas de los últimos años que contienen núcleos con más de un procesador, ya que realmente pueden ejecutar varios procesos paralelos.</p>
<p><b>Fuentes AutoResetEvent</b></p>
<p><b><a href="http://msdn.microsoft.com/es-es/library/system.threading.autoresetevent(v=VS.90).aspx">http://msdn.microsoft.com/es-es/library/system.threading.autoresetevent(v=VS.90).aspx</a></b></p>
<p><a href="http://blogs.msdn.com/b/johnlee/archive/2007/07/10/waithandle-waitall-for-multiple-handles-on-a-sta-thread-is-not-supported.aspx">http://blogs.msdn.com/b/johnlee/archive/2007/07/10/waithandle-waitall-for-multiple-handles-on-a-sta-thread-is-not-supported.aspx</a></p>
<p><b>Fuentes BackgroundWorker</b></p>
<p><a href="http://msdn.microsoft.com/es-es/library/ms233672(v=VS.80).aspx">http://msdn.microsoft.com/es-es/library/ms233672(v=VS.80).aspx</a></p>
<p><a href="http://msdn.microsoft.com/es-es/library/8xs8549b(VS.80).aspx">http://msdn.microsoft.com/es-es/library/8xs8549b(VS.80).aspx</a></p>
<p><a href="http://dotneat.iloire.com/2010/03/06/ejemplo-backgroundworker-en-csharp/">http://dotneat.iloire.com/2010/03/06/ejemplo-backgroundworker-en-csharp/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://copstone.com/2010/11/como-crear-una-aplicacin-multihilos-multithread-autoresetevent-vs-backgroundworker-en-visual-studio-2008-c/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Manejando la Cultura en nuestras Aplicaciones</title>
		<link>http://copstone.com/2010/07/manejando-la-cultura-en-nuestras-aplicaciones/</link>
		<comments>http://copstone.com/2010/07/manejando-la-cultura-en-nuestras-aplicaciones/#comments</comments>
		<pubDate>Mon, 26 Jul 2010 17:40:00 +0000</pubDate>
		<dc:creator>Victor Parasi</dc:creator>
				<category><![CDATA[Productividad]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://copstone.com/?p=1085</guid>
		<description><![CDATA[Sabias que puedes ejecutar tus aplicaciones en un idioma distinto al de tu Sistema Operativo, te dejo este post para que te enteres de que se trata.]]></description>
			<content:encoded><![CDATA[<p>Cuando me refiero al término Cultura dentro de una aplicación, me refiero entre otras cosas al sistema de escritura, formato de separación decimal, símbolo de la moneda, formato de las fechas; en fin, todo aquello que es propio de un idioma y que no es respetado, necesariamente, por los demás.</p>
<p>En esta oportunidad veremos, a partir de una aplicación Consola, como podemos acceder a la configuración regional y luego definir una para poder aplicarla dentro de nuestra aplicación, sin tener la necesidad de cambiar la de nuestro sistema operativo.</p>
<p>Comenzaremos diciendo que para poder utilizar las clases que indicaré, debes de asegurarte de tener referencia al siguiente namespace:</p>
<pre style="width: 619px; height: 29px" class="brush:csharp;auto-links:false;collapse:false;first-line:1;gutter:true;smart-tabs:true;wrap-lines:true;%SYNTAX_HIGHLIGHTER_CSHARP%">using System.Globalization;</pre>
<p>Utilizar este namespace nos permite acceder, entre otras cosas, a la clase CultureInfo. Esta clase es la que nos va a permitir trabajar con la cultura actual y cambiarla dentro de nuestra aplicación.</p>
<p>Veamos como podemos acceder a la cultura actual de nuestra aplicación obtener sus principales características:</p>
<pre class="brush:csharp;auto-links:false;collapse:false;first-line:1;gutter:true;smart-tabs:true;wrap-lines:true;%SYNTAX_HIGHLIGHTER_CSHARP%">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//Namespace
using System.Globalization;

namespace CultureInfoConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            //Obtenemos la Cultura Actual
            CultureInfo culturaactual = CultureInfo.CurrentCulture;
            //CultureInfo culturaactual=CultureInfo.CurrentCulture;
            //INFORMACION
            Console.WriteLine(&quot;CompareInfo: {0}&quot;, culturaactual.CompareInfo);
            Console.WriteLine(&quot;DisplayName : {0}&quot;, culturaactual.DisplayName);
            Console.WriteLine(&quot;EnglishName: {0}&quot;, culturaactual.EnglishName);
            Console.WriteLine(&quot;IsNeutralCulture: {0}&quot;, culturaactual.IsNeutralCulture);
            Console.WriteLine(&quot;IsReadOnly: {0}&quot;, culturaactual.IsReadOnly);
            Console.WriteLine(&quot;LCID: {0}&quot;, culturaactual.LCID);
            Console.WriteLine(&quot;Name: {0}&quot;, culturaactual.Name);
            Console.WriteLine(&quot;NativeName: {0}&quot;, culturaactual.NativeName);
            Console.WriteLine(&quot;Parent: {0}&quot;, culturaactual.Parent);
            Console.WriteLine(&quot;TextInfo: {0}&quot;, culturaactual.TextInfo);
            //MONEDA
            Console.WriteLine(&quot;CurrencySymbol: {0}&quot;, culturaactual.NumberFormat.CurrencySymbol);
            Console.WriteLine(&quot;CurrencyDecimalSeparator: {0}&quot;, culturaactual.NumberFormat.CurrencyDecimalSeparator);
            Console.WriteLine(&quot;CurrencyDecimalDigits: {0}&quot;, culturaactual.NumberFormat.CurrencyDecimalDigits);
            //FECHA y HORA
            Console.WriteLine(&quot;ShortDatePattern: {0}&quot;, culturaactual.DateTimeFormat.ShortDatePattern);
            Console.WriteLine(&quot;DateSeparator: {0}&quot;, culturaactual.DateTimeFormat.DateSeparator);
            Console.WriteLine(&quot;ShortTimePattern: {0}&quot;, culturaactual.DateTimeFormat.ShortTimePattern);
            Console.WriteLine(&quot;TimeSeparator: {0}&quot;, culturaactual.DateTimeFormat.TimeSeparator);

            Console.WriteLine(&quot;\nDias de la semana : &quot;);
            foreach (string s in culturaactual.DateTimeFormat.DayNames)
            { Console.Write(&quot;{0} &quot; ,s.ToUpper() ); }

            Console.WriteLine(&quot;\nMeses del año : &quot;);
            //MESES DEL AÑO
            foreach (string s in culturaactual.DateTimeFormat.MonthNames )
            { Console.Write(&quot;{0} &quot;,s.ToUpper()); }

             Console.ReadLine();

        }
    }
}</pre>
<p>En el código anterior, como puedes apreciar, he obtenido la cultura de nuestra aplicación a través de: <strong>CultureInfo.CurrentCulture, </strong>y a partir de esto podemos acceder a la características propia de la cultura.</p>
<p>En mi caso, mi cultura por defecto es <strong>&quot;en-US&quot;</strong>, pero esto no es impedimento para que pueda cambiarla dentro de mi aplicación, mira el siguiente ejemplo:</p>
<pre class="brush:csharp;auto-links:false;collapse:false;first-line:1;gutter:true;smart-tabs:true;wrap-lines:true;%SYNTAX_HIGHLIGHTER_CSHARP%">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//Namespace
using System.Globalization;

namespace CultureInfoConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            //Definimos una nueva cultura
            CultureInfo nuevacultura = new System.Globalization.CultureInfo(&quot;es-PE&quot;, false);
            //Asignamos la nueva cultura a nuestra aplicación
            System.Threading.Thread.CurrentThread.CurrentCulture = nuevacultura;
            //Obtenemos la Cultura Actual
            CultureInfo culturaactual = CultureInfo.CurrentCulture;
            //CultureInfo culturaactual=CultureInfo.CurrentCulture;
            //INFORMACION
            Console.WriteLine(&quot;CompareInfo: {0}&quot;, culturaactual.CompareInfo);
            Console.WriteLine(&quot;DisplayName : {0}&quot;, culturaactual.DisplayName);
            Console.WriteLine(&quot;EnglishName: {0}&quot;, culturaactual.EnglishName);
            Console.WriteLine(&quot;IsNeutralCulture: {0}&quot;, culturaactual.IsNeutralCulture);
            Console.WriteLine(&quot;IsReadOnly: {0}&quot;, culturaactual.IsReadOnly);
            Console.WriteLine(&quot;LCID: {0}&quot;, culturaactual.LCID);
            Console.WriteLine(&quot;Name: {0}&quot;, culturaactual.Name);
            Console.WriteLine(&quot;NativeName: {0}&quot;, culturaactual.NativeName);
            Console.WriteLine(&quot;Parent: {0}&quot;, culturaactual.Parent);
            Console.WriteLine(&quot;TextInfo: {0}&quot;, culturaactual.TextInfo);
            //MONEDA
            Console.WriteLine(&quot;CurrencySymbol: {0}&quot;, culturaactual.NumberFormat.CurrencySymbol);
            Console.WriteLine(&quot;CurrencyDecimalSeparator: {0}&quot;, culturaactual.NumberFormat.CurrencyDecimalSeparator);
            Console.WriteLine(&quot;CurrencyDecimalDigits: {0}&quot;, culturaactual.NumberFormat.CurrencyDecimalDigits);
            //FECHA y HORA
            Console.WriteLine(&quot;ShortDatePattern: {0}&quot;, culturaactual.DateTimeFormat.ShortDatePattern);
            Console.WriteLine(&quot;DateSeparator: {0}&quot;, culturaactual.DateTimeFormat.DateSeparator);
            Console.WriteLine(&quot;ShortTimePattern: {0}&quot;, culturaactual.DateTimeFormat.ShortTimePattern);
            Console.WriteLine(&quot;TimeSeparator: {0}&quot;, culturaactual.DateTimeFormat.TimeSeparator);
            Console.WriteLine(&quot;\nDias de la semana : &quot;);
            foreach (string s in culturaactual.DateTimeFormat.DayNames)
            { Console.Write(&quot;{0} &quot; ,s.ToUpper() ); }
            Console.WriteLine(&quot;\nMeses del año : &quot;);
            //MESES DEL AÑO
            foreach (string s in culturaactual.DateTimeFormat.MonthNames )
            { Console.Write(&quot;{0} &quot;,s.ToUpper()); }
            Console.ReadLine();

        }
    }
}</pre>
<p>En la primera línea, dentro de Program, puedes apreciar que estoy definiendo una cultura &quot;<strong>es-PE</strong>&quot;, español Perú, la cual la asigno como cultura actual de mi aplicación.</p>
<p>Hacer esto, entre otras cosas, me permite acceder a los nombres del día y mes en el idioma correcto y poder hacer algo con estas posteriormente.</p>
<p>Como puedes apreciar, manejar las culturas en nuestras aplicaciones, es bastante sencillo, permitiéndonos personalizar nuestra aplicación dependiendo del idioma que desees ejecutar. En un próximo post veremos como hacerlo con una aplicación Windows.</p>
]]></content:encoded>
			<wfw:commentRss>http://copstone.com/2010/07/manejando-la-cultura-en-nuestras-aplicaciones/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Consumiendo un servicio WCF</title>
		<link>http://copstone.com/2010/07/consumiendo-un-servicio-wcf/</link>
		<comments>http://copstone.com/2010/07/consumiendo-un-servicio-wcf/#comments</comments>
		<pubDate>Thu, 22 Jul 2010 15:54:00 +0000</pubDate>
		<dc:creator>Victor Parasi</dc:creator>
				<category><![CDATA[net]]></category>
		<category><![CDATA[Productividad]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[WCF]]></category>

		<guid isPermaLink="false">http://copstone.com/?p=1082</guid>
		<description><![CDATA[En el post anterior vimos como implementar un servicio WCF. Ahora aprenderemos a consumirlo desde una sencilla aplicación consola en C#.]]></description>
			<content:encoded><![CDATA[<p>En el post <a href="http://copstone.com/2010/07/creando-un-proyecto-wcf/">anterior</a>, vimos como crear un proyecto del tipo WCF, donde exponíamos en la Web, una serie de operaciones definidas por un contrato dentro de un proveedor y un consumidor.</p>
<p>Mi objetivo en este post es ayudarte a consumir este servicio, desde una simple aplicación del tipo consola para que veas lo fácil que es.</p>
<p>Antes de empezar te diré que voy a trabajar sobre la solución anterior, agregando a ésta los proyectos que voy a ir mencionando.</p>
<h2>Paso 1. Crear un WCF Service Application</h2>
<p>Luego de abrir la solución anterior, con el servicio definido, vamos a adicionar un WCF Service Application.</p>
<p><a href="http://copstone.com/wp-content/uploads/2010/07/image3.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://copstone.com/wp-content/uploads/2010/07/image_thumb4.png" width="525" height="273" /></a> </p>
<p>Esto agregará a la solución una aplicación, con dos clases por defecto, las cuales deberás eliminar. Mira la siguiente figura.</p>
<p><a href="http://copstone.com/wp-content/uploads/2010/07/image4.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://copstone.com/wp-content/uploads/2010/07/image_thumb5.png" width="300" height="135" /></a></p>
<p><a href="http://copstone.com/wp-content/uploads/2010/07/image5.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://copstone.com/wp-content/uploads/2010/07/image_thumb6.png" width="293" height="132" /></a>&#160; </p>
</p>
<p>Luego de eliminado los dos archivos, voy a renombrar Service1.svc por MiServicio.svc. De forma que el proyecto quede de la siguiente forma:</p>
<p><a href="http://copstone.com/wp-content/uploads/2010/07/image6.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://copstone.com/wp-content/uploads/2010/07/image_thumb7.png" width="288" height="190" /></a> </p>
<h2>Paso 2. Referenciar al WCFServiceLibrary creado</h2>
<p>Recuerda que en el post anterior, creamos el servicio en un WCFServiceLibrary, por lo que ahora, en el proyecto que acabamos de agregar en el paso anterior, vamos a referenciarlo. Recuerda que basta con dar clic derecho del mouse sobre el proyecto WCF Service Application y pulsar Add Reference.</p>
<p>En la pantalla que aparece, escogemos el tab de Proyects y seleccionamos el proyecto que contiene nuestro servicio definido.</p>
<h2>Paso 3. Apuntando al servicio correcto</h2>
<p>Luego de agregada la referencia, vamos a indicarle a nuestro proyecto WCF Service Application que apunte al servicio definido.</p>
<p>Para hacer esto, seleccionaremos MiServicio.svc </p>
<p><a href="http://copstone.com/wp-content/uploads/2010/07/image7.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://copstone.com/wp-content/uploads/2010/07/image_thumb8.png" width="217" height="143" /></a> </p>
<p>y damos clic derecho para ingresar a la opción <strong>View Code,</strong> o pulsamos simplemente <strong>F7,</strong> luego de seleccionar el archivo.</p>
<p>Al acceder a esta opción, podremos visualizar el siguiente código:</p>
<pre style="width: 636px; height: 46px" class="brush:xml;auto-links:false;collapse:false;first-line:1;gutter:true;smart-tabs:true;wrap-lines:true;%SYNTAX_HIGHLIGHTER_XML%">&lt;%@ ServiceHost Language=&quot;C#&quot; Debug=&quot;true&quot; Service=&quot;WcfService1.Service1&quot; CodeBehind=&quot;Service1.svc.cs&quot; %&gt;</pre>
<p>Este código hace referencia al Servicio, por lo que debemos de cambiar la sección de Service y eliminar el bloque de CodeBehind, dejando el código de la siguiente forma.</p>
<pre style="width: 619px; height: 29px" class="brush:xml;auto-links:false;collapse:false;first-line:1;gutter:true;smart-tabs:true;wrap-lines:true;%SYNTAX_HIGHLIGHTER_XML%">&lt;%@ ServiceHost Language=&quot;C#&quot; Debug=&quot;true&quot; Service=&quot;WCFServiceLibrary.MiServicio&quot;%&gt;</pre>
<p>Recuerda que en el paso anterior hicimos referencia al WCF Service Library definido, y es allí donde encontramos el servicio WCFServiceLibrary.MiServicio, por lo que podemos usarlo sin ningún problema.</p>
<p>Luego de realizar los cambios, ejecutemos la aplicación creada para ver si todo esta OK.</p>
<p>Te debe de salir lo siguiente:</p>
<p><a href="http://copstone.com/wp-content/uploads/2010/07/image8.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://copstone.com/wp-content/uploads/2010/07/image_thumb9.png" width="535" height="223" /></a> </p>
<p>Ya que nos aseguramos que el servicio funciona adecuadamente, vamos a crear un proyecto del tipo consola.</p>
<h2>Paso 4: Crear un Proyecto del Consola</h2>
<p>No voy a explicar mucho en este paso, porque ya hemos creado muchos proyectos consola en el blog. Lo único que aclararé es que debes de adicionar el proyecto a la solución que contiene hasta entonces dos proyectos, uno del tipo WCF Service Library y el WCF Service Application.</p>
<p>&#160;</p>
<h2>Paso 5: Referenciar&#160; System.ServiceModel</h2>
<p>Al Proyecto consola le vamos a agregar referencia, en primer lugar al Assembly System.ServiceModel. Recuerda que para hacer esto basta con ir a la opción Add Reference, y en la pantalla que aparece, buscar System.ServiceModel en el tab .Net.</p>
<h2>Paso 6: Referenciar&#160; el Servicio Creado</h2>
<p>Bueno, para poder usar el Servicio WCF, debemos de referenciarlo. Para hacer esto debemos de dar clic derecho del mouse sobre el proyecto Consola y seleccionar la opción Add Service Reference. En la pantalla que aparece seleccionamos Discover-&gt; Services in Solution</p>
<p>Aparecerán listados los servicios que tenemos, seleccionaremos el que dice <strong>MiServicio.svc</strong>. Mira la siguiente imagen.</p>
<p><a href="http://copstone.com/wp-content/uploads/2010/07/image9.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://copstone.com/wp-content/uploads/2010/07/image_thumb10.png" width="421" height="351" /></a> </p>
<p>Aprecia que he cambiado también el <strong>Namespace, </strong>en la parte inferior.</p>
<p>Luego de seleccionar el servicio y cambiar el Namespace, pulsar OK.</p>
<h2>Paso 7: Codificar la invocación a las Operaciones del Servicio</h2>
<p>Cambiar el código de Progrma.cs del proyecto Consola por el siguiente:</p>
<p>&#160;</p>
<pre style="width: 648px; height: 498px" class="brush:csharp;auto-links:false;collapse:false;first-line:1;gutter:true;smart-tabs:true;wrap-lines:true;%SYNTAX_HIGHLIGHTER_CSHARP%">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel; //Referencia al Assembly Referenciado

namespace ConsoleApplicationRunService
{
    class Program
    {
        static void Main(string[] args)
        {
            //Definición del Cliente al Servicio referenciado
            MiServicioReference.MiServicioClient cliente = new
					MiServicioReference.MiServicioClient();
            //Invocación a la Operación Factorial
            Console.WriteLine(&quot;El Factorial de 5 es : {0}&quot;,cliente.Factorial(5));
            Console.WriteLine(&quot;Los 10 Primeros numeros Fibonacci son : &quot;);
            //Invocación a la Operación Numeros_Fibonacci
            foreach (int i in cliente.Numeros_Fibonacci(10))
                Console.WriteLine(&quot;{0}&quot;, i);
            //Invocación a la Operación Sumatoria_Fibonacci

            Console.WriteLine(&quot;La suma de los 10 primero numeros fibonacci es : {0}&quot;,
					cliente.Sumatoria_Fibonacci(10));
            Console.ReadLine(); 

        }
    }
}</pre>
<p>Ejecuta la aplicación y puedes apreciar que se invoca al servicio WCF creado, mostrando en pantalla el resultado de la invocación a éstos.</p>
]]></content:encoded>
			<wfw:commentRss>http://copstone.com/2010/07/consumiendo-un-servicio-wcf/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Creando un proyecto WCF</title>
		<link>http://copstone.com/2010/07/creando-un-proyecto-wcf/</link>
		<comments>http://copstone.com/2010/07/creando-un-proyecto-wcf/#comments</comments>
		<pubDate>Tue, 20 Jul 2010 17:34:00 +0000</pubDate>
		<dc:creator>Victor Parasi</dc:creator>
				<category><![CDATA[Productividad]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[WCF]]></category>

		<guid isPermaLink="false">http://copstone.com/?p=1062</guid>
		<description><![CDATA[En el artículo de SOA, vimos que en la actualidad lo importante no es sólo que tu aplicación funcione bien, sino que funcione acoplada al entorno sobre el cual será puesto en producción,comunicándose con las aplicaciones existentes y futuras mediante un concepto llamado Servicios. En este artículo veremos como implementar un Servicio mediante WCF de Microsoft.]]></description>
			<content:encoded><![CDATA[<p>En el post <a href="http://copstone.com/2010/07/service-oriented-arquitecture/">anterior</a>, explique rápidamente que era la arquitectura SOA. En este post veremos que alternativa tenemos para cumplir con lo que nos indica esta arquitectura.</p>
<p>Microsoft desde ya hace unos años, viene trabajando con el concepto de&#160; Windows Communication Foundation (WCF).&#160; Voy a transcribir la definición oficial de WCF que nos da Microsoft en su página <a href="http://msdn.microsoft.com/es-es/library/ms731082.aspx">web</a>.</p>
<p><em>Windows Communication Foundation (WCF) es un marco de trabajo para la creación de aplicaciones orientadas a servicios. Con WCF, es posible enviar datos como mensajes asincrónicos de un extremo de servicio a otro. Un extremo de servicio puede formar parte de un servicio disponible continuamente hospedado por IIS, o puede ser un servicio hospedado en una aplicación. Un extremo puede ser un cliente de un servicio que solicita datos de un extremo de servicio. Los mensajes pueden ser tan simples como un carácter o una palabra que se envía como XML, o tan complejos como una secuencia de datos binarios. A continuación se indican unos cuantos escenarios de ejemplo:</em></p>
<ul>
<li><em>Un servicio seguro para procesar transacciones comerciales. </em></li>
<li><em>Un servicio que proporciona datos actualizados a otras personas, como un informe sobre tráfico u otro servicio de supervisión.</em> </li>
<li><em>Un servicio de chat que permite a dos personas comunicarse o intercambiar datos en tiempo real.</em> </li>
<li><em>Una aplicación de panel que sondea los datos de uno o varios servicios y los muestra en una presentación lógica. </em></li>
<li><em>Exponer un flujo de trabajo implementado utilizando Windows Workflow Foundation como un servicio WCF.</em> </li>
<li><em>Una aplicación de Silverlight para sondear un servicio en busca de las fuentes de datos más recientes.</em> </li>
</ul>
<p>Gráficamente, veamos que podemos ganar implementando servicios WCF al momento de desarrollar nuestras aplicaciones.</p>
<p><img src="http://i.msdn.microsoft.com/dynimg/IC303719.jpg" width="392" height="292" /></p>
<p>Como podemos apreciar, WCF nos brinda un canal seguro de comunicación (a través de contratos) no solo entre aplicaciones de una misma máquina, sino a través de una red que puede estar conformada por servidores Windows o Linux (Interoperabilidad).</p>
<p>Bueno, basta de teoría y veamos como crear un proyecto del tipo WCF en Visual Studio 2010 y utilizando las características que nos da el .Net Framework 4.0</p>
<h2>Paso 1: Definir el Contrato</h2>
<p>Cuando hablamos de servicios, recuerda que siempre debe de haber un proveedor y un consumidor del servicio, por lo que es necesario definir cómo se llevará la comunicación entre estos dos entes. A este proceso le llamaremos: Definición del Contrato.</p>
<p>En el Contrato definiremos básicamente lo siguiente:</p>
<ul>
<li>Las operaciones que se podrán realizar. </li>
<li>Las firmas y los tipos de datos que se enviarán y/o recibirán durante la invocación de las operaciones. </li>
<li>Los protocolos y formatos de serialización que se utilizan para llevar a cabo la comunicación. </li>
</ul>
<p>Luego de definido esto, recién podemos llevarlo a la programación.</p>
<p>Para el ejemplo voy a definir algo bastante sencillo. Haremos un contrato para permitir la realización de las siguientes operaciones básicas: </p>
<ul>
<li><strong>Factorial de un número</strong>
<pre style="width: 586px; height: 29px" class="brush:csharp;auto-links:false;collapse:false;first-line:1;gutter:true;smart-tabs:true;wrap-lines:true;%SYNTAX_HIGHLIGHTER_CSHARP%">long Factorial(long x);</pre>
</li>
<li><strong>Devolver una Lista de enteros, con los &quot;n&quot; primeros números de la serie de Fibonacci.</strong>
<pre class="brush:csharp;auto-links:false;collapse:false;first-line:1;gutter:true;smart-tabs:true;wrap-lines:true;%SYNTAX_HIGHLIGHTER_CSHARP%">List&lt;int&gt; Numeros_Fibobacci(int n);</pre>
</li>
</ul>
<ul>
<li><strong>Suma de los primeros &quot;n&quot; números de la serie de Fibonacci.</strong>
<pre style="width: 611px; height: 29px" class="brush:csharp;auto-links:false;collapse:false;first-line:1;gutter:true;smart-tabs:true;wrap-lines:true;%SYNTAX_HIGHLIGHTER_CSHARP%">double Sumatoria_Fibonacci(int n);</pre>
</li>
</ul>
<p>&#160;</p>
<h2>Paso 2: Creando un Proyecto del Tipo WCF Service Library</h2>
<p>Luego de definido las operaciones y el contrato, vamos a crear una aplicación del tipo WCF Service Library, para implementarlos.</p>
<p><a href="http://copstone.com/wp-content/uploads/2010/07/image.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://copstone.com/wp-content/uploads/2010/07/image_thumb.png" width="539" height="261" /></a> </p>
</p>
<p>Luego de creada la aplicación te pediría que borres los archivos IService1.cs y Service1.cs para que aprendamos a crear los servicios, sin necesidad de una ayuda.</p>
<p>Luego de borrar ambos archivos, vamos a adicionar (Add New Item) a nuestro proyecto una Clase (llamado MiServicio) y una Interface (llamada IMiServicio). Te dejo la siguiente imagen para que veas a lo que me refiero.</p>
<p><a href="http://copstone.com/wp-content/uploads/2010/07/image1.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://copstone.com/wp-content/uploads/2010/07/image_thumb1.png" width="444" height="319" /></a> </p>
<p>Luego de creada la Clase y la Interface, debes de adicionar el siguiente using en ambas: </p>
<pre style="width: 619px; height: 29px" class="brush:csharp;auto-links:false;collapse:false;first-line:1;gutter:true;smart-tabs:true;wrap-lines:true;%SYNTAX_HIGHLIGHTER_CSHARP%">using System.ServiceModel;</pre>
<p>Ahora si, vamos a programar las operaciones que hemos definido dentro de nuestro contrato. Empezaremos con la Interface.</p>
<h2>Paso 3: Codificando la Interface</h2>
<p>Luego de agregada la referencia, debemos de adicionar un atributo a nuestra interface, el atributo es [ServiceContract], quedando nuestro código de la siguiente forma:</p>
<pre class="brush:csharp;auto-links:false;collapse:false;first-line:1;gutter:true;smart-tabs:true;wrap-lines:true;%SYNTAX_HIGHLIGHTER_CSHARP%">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace WCFServiceLibrary
{
    [ServiceContract]
    public interface IMiServicio
    {

    }
}</pre>
<p>Ahora codificaremos sólo&#160; las firma de nuestra operaciones anteponiendo a cada una el atributo [OperationContract] , quedando nuestro código de la siguiente forma:</p>
<pre class="brush:csharp;auto-links:false;collapse:false;first-line:1;gutter:true;smart-tabs:true;wrap-lines:true;%SYNTAX_HIGHLIGHTER_CSHARP%">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace WCFServiceLibrary
{
    [ServiceContract]
    public interface IMiServicio
    {
        [OperationContract]
        long Factorial(long x);

        [OperationContract]
        double Sumatoria_Fibonacci(int n);

        [OperationContract]
        List&lt;int&gt; Numeros_Fibobacci(int n);

    }
}</pre>
<p>&#160;</p>
<h2>Paso 4: Codificando la Clase</h2>
<p>Terminada la Interface, debemos de implementar cada Operación, esto lo hacemos en la clase, por lo que debemos de indicar, mediante un identificador, que la clase va a implementar los métodos definidos en la Interface.</p>
<pre class="brush:csharp;auto-links:false;collapse:false;first-line:1;gutter:true;smart-tabs:true;wrap-lines:true;%SYNTAX_HIGHLIGHTER_CSHARP%">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace WCFServiceLibrary
{
    //Al momento de definir la clase, indicamos que implementará los
    //métodos de la Interface IMiServicio
    public class MiServicio:IMiServicio
    {

    }
}</pre>
<p>Luego implementamos los métodos que hemos definido.</p>
<pre class="brush:csharp;auto-links:false;collapse:false;first-line:1;gutter:true;smart-tabs:true;wrap-lines:true;%SYNTAX_HIGHLIGHTER_CSHARP%">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace WCFServiceLibrary
{
    //Al momento de definir la clase, indicamos que implementará los
    //métodos de la Interface IMiServicio
    public class MiServicio:IMiServicio
    {
        public long Factorial(long x)
        {
            if (x &lt;= 1 ) return 1;
            else
            {
                return x*Factorial(x - 1);
            }
        }

        public double Sumatoria_Fibonacci(int n)
        {
            List&lt;int&gt; numeros = Numeros_Fibobacci(n);
            return numeros.Sum();
       }

        public List&lt;int&gt; Numeros_Fibobacci(int n)
        {
            List&lt;int&gt; numeros = new List&lt;int&gt;();
            int a, b, c;
            a = 1;
            b = 0;
            for (int i = 0; i &lt; n;i++ )
            {
                c = a + b;
                numeros.Add(c);
                a = b;
                b = c;

            }
            return numeros;
        }

    }
}</pre>
<p>Como puedes apreciar, la implementación de las operaciones la he utilizado de forma normal, sin ningún operador o atributo diferente a los que ya conoces.</p>
<h2>Paso 5: Cambiando el Archivo de Configuración</h2>
<p>&#160;</p>
<p>Luego de definir el contrato, es necesario publicarlo para que pueda ser consumido, esto lo hacemos colocando el nombre del servicio, donde esta publicado, y el tipo de enlace que permitirá.</p>
<p>Voy a colocar parte del App.config para que veas que información se coloca por cada uno de los servicios:</p>
<pre style="width: 644px; height: 444px" class="brush:xml;auto-links:false;collapse:false;first-line:1;gutter:true;smart-tabs:true;wrap-lines:true;%SYNTAX_HIGHLIGHTER_XML%">&lt;system.serviceModel&gt;
    &lt;services&gt;
	&lt;!-- Nombre del Servicio (Namespace.NombreClase) --&gt;
      &lt;service name=&quot;WCFServiceLibrary.MiServicio&quot;&gt;
        &lt;host&gt;
          &lt;!-- Direccion del Servicio--&gt;
	  &lt;baseAddresses&gt;
            &lt;add baseAddress = &quot;http://localhost:8732/Design_Time_Addresses/WCFServiceLibrary/MiServicio/&quot; /&gt;
          &lt;/baseAddresses&gt;
        &lt;/host&gt;
        &lt;!-- Service Endpoints --&gt;
        &lt;!-- Unless fully qualified, address is relative to base address supplied above --&gt;
        &lt;endpoint address =&quot;&quot; binding=&quot;wsHttpBinding&quot; contract=&quot;WCFServiceLibrary.IMiServicio&quot;&gt;
          &lt;!--
              Upon deployment, the following identity element should be removed or replaced to reflect the
              identity under which the deployed service runs.  If removed, WCF will infer an appropriate identity
              automatically.
          --&gt;
          &lt;identity&gt;
            &lt;dns value=&quot;localhost&quot;/&gt;
          &lt;/identity&gt;
        &lt;/endpoint&gt;
        &lt;!-- Metadata Endpoints --&gt;
        &lt;!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. --&gt;
        &lt;!-- This endpoint does not use a secure binding and should be secured or removed before deployment --&gt;
        &lt;endpoint address=&quot;mex&quot; binding=&quot;mexHttpBinding&quot; contract=&quot;IMetadataExchange&quot;/&gt;
      &lt;/service&gt;
    &lt;/services&gt;</pre>
<p>Luego de realizar los cambios podemos probar nuestros servicios, ejecutando nuestra aplicación con F5</p>
<h2>Paso 6: Probando nuestro Servicio WCF</h2>
<p><a href="http://copstone.com/wp-content/uploads/2010/07/image2.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://copstone.com/wp-content/uploads/2010/07/image_thumb2.png" width="566" height="273" /></a></p>
<p>Al ejecutar la aplicación creada, Visal Studio, ejecuta WCF Test Client, añadiendo el servicio creado y las operaciones que este contempla, de forma que podremos probar si estas se ejecutan adecuadamente.</p>
<p>Para probar cada operación, basta con dar doble clic en una de ellas y en la pantalla que aparece, dar valores a los datos requeridos para luego invocarlos.&#160; Mira la siguiente imagen, donde pruebo la Función Factorial para un valor de x=5.</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://copstone.com/wp-content/uploads/2010/07/image_thumb3.png" width="582" height="281" /></p>
<p>Como podrás ver, es bastante sencillo implementar un servicio WCF. Si bien es cierto he usado operaciones bastante sencillas, tu puedes utilizar lo aprendido aquí para trabajar con Base de Datos, por ejemplo, de forma que trabajes a través de servicios que a su vez puedan ser aprovechadas por otras aplicaciones. Espero te sea de ayuda este post para tus trabajos posteriores.</p>
]]></content:encoded>
			<wfw:commentRss>http://copstone.com/2010/07/creando-un-proyecto-wcf/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Service Oriented Arquitecture</title>
		<link>http://copstone.com/2010/07/service-oriented-arquitecture/</link>
		<comments>http://copstone.com/2010/07/service-oriented-arquitecture/#comments</comments>
		<pubDate>Thu, 01 Jul 2010 18:15:25 +0000</pubDate>
		<dc:creator>Victor Parasi</dc:creator>
				<category><![CDATA[Productividad]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://copstone.com/?p=1045</guid>
		<description><![CDATA[Si crees que con sólo programar tus aplicaciones es suficiente, te equivocas. Debes de tomar en cuenta como va a encajar tu aplicación dentro del negocio que lo utiliza, piensa que no es una isla sino que debe de coexistir con otras aplicaciones actuales o futuras. Lee este artículo y entérate cómo puedes lograr esto.]]></description>
			<content:encoded><![CDATA[<p>Desde ya hace unos años, dada la diversidad que existe en plataformas de desarrollo y aplicaciones desarrolladas en cada una de éstas, lo que se viene buscando es la interoperabilidad, léase, la comunicación y coexistencia entre todas estas aplicaciones.</p>
<p>En busca de esta comunicación, una de las Arquitecturas más usadas actualmente para el desarrollo de aplicaciones que existe es SOA (Arquitectura Basada en Servicios). SOA, no es un lenguaje ni un software, es un modelo que debemos seguir para implementar aplicaciones y que éstas puedan exponer ciertos &quot;servicios&quot;, que pueden ser invocados o consumidos por otras aplicaciones.</p>
<p>Te muestro un ejemplo, digamos que acabas de terminar de desarrollar, para una misma empresa, dos aplicaciones , una aplicación encargada de manejar el ingreso y salida de materiales (Logística) y otra encargada de abastecimiento de materiales (Compra).</p>
<p>Imagínate ahora que son las mejores aplicaciones que hiciste hasta ahora, funcionan excelente, pero existe un pequeño problema. El encargado de comprar el material, no recibe notificación alguna cuando el material solicitado llega y vuelve a pedir más de ese mismo material. O peor aún, el encargado de logística a pesar de tener controlado su ingreso y salida de materiales, no expone esta información al resto de áreas de la empresa. En conclusión, pueden ser dos buenas aplicaciones pero funcionan como una isla, no se comunican, dificultando que la información fluya por las diversas áreas una misma empresa, como puedes ver este es un gran problema.</p>
<p>Si este ejemplo pasa en dos aplicaciones realizadas por una misma persona, imagínate que puede pasar con aplicaciones realizadas por diversos proveedores y quizás en diversas plataformas.</p>
<p>SOA, lo que propone es un modelo de trabajo donde las aplicaciones que se realizan, expongan parte de sus responsabilidades a otras que lo necesiten de forma que podamos armonizar el trabajo. Si hablamos de una empresa, para que podamos armonizar y soportar el trabajo entre la diversas áreas: Logística, Compras, Ventas, Finanzas, Contabilidad, etc . Ahora, esto no es una tarea sencilla, implica un arduo trabajo .</p>
<p>SOA, promueve la exposición de servicios por parte de una aplicación hacia otra, por lo que debemos tener en claro los siguiente conceptos:</p>
<table style="border-collapse: collapse" class="h" border="1" cellspacing="0" cellpadding="0" width="2" s="s">
<tbody>
<tr>
<td>Proveedor</td>
<td>función cubierta por una aplicación que provee de un servicio a ser consumido por otra aplicación.</td>
</tr>
<tr>
<td>Consumidor</td>
<td>función cubierta por una aplicación que solicita de un servicio a un proveedor.</td>
</tr>
<tr>
<td>Servicio</td>
<td>exposición de una funcionalidad por parte de un proveedor, la cual es definida e implementada por una interfaz previamente establecida y la cual debe ser conocida por los consumidores.</td>
</tr>
<tr>
<td>Coordinación u Orquestación</td>
<td>Si hablamos de servicio, proveedores y consumidores, indudablemente no estamos hablando de UN servicio, sino de N servicios, lo mismo que proveedores y consumidores.&#160; Si tenemos N servicios, debemos de ser capaces de coordinar el trabajo entre estos de forma que asegurar el flujo y procesamiento de datos entre estos servicios definidos.</td>
</tr>
</tbody>
</table>
<p>Como puedes apreciar, no es una tarea sencilla. Es una tarea ardua de coordinación permanente, que empieza con una buena definición de los procesos y luego de las aplicaciones que den soporte a los procesos definidos.</p>
<p>SOA promueve el uso de servicios como exposición de las responsabilidades entre los aplicaciones (o sistemas) y para desarrollar esto ha encontrado en los Servicios Web, la mejor forma de poder implementar este concepto, dado que permite a un proveedor publicar un servicio y al consumidor consumirlo, utilizando un soporte independiente como los son <strong>WSDL</strong> (Estándar que permite definir cualquier servicio Web) y <strong>SOAP</strong> (Protocolo que define y permite como se puede intercambiar información, mediante el uso de XML). Veamos el siguiente gráfico</p>
<p><img style="display: block; float: none; margin-left: auto; margin-right: auto" border="0" alt="" src="http://photos1.blogger.com/blogger/6879/2553/320/SOA%20Tradicional.0.jpg" /></p>
<p>Como podemos ver en el gráfico anterior, podemos ver que como interactúan los proveedores con los consumidores sin importar de la plataforma que estamos hablando.</p>
<p>Ahora, si colocamos un concepto adicional como Orquestación vemos que la arquitectura SOA, toma un grado mayor de complejidad, debido a que estamos hablando no sólo de WSDL y SOAP, sino de conceptos como Seguridad, Transacción, Administración, Registro, etc, siendo estos siempre soportados por estándares independientes de los lenguajes en este caso, los WS.</p>
<p>&#160;</p>
<p><img style="display: block; float: none; margin-left: auto; margin-right: auto" border="0" alt="" src="http://photos1.blogger.com/blogger/6879/2553/320/SOA%202%20Generacion.jpg" width="375" height="273" />&#160;</p>
<p>Ahora, SOA, no es sólo servicios, bueno si lo es, pero siempre debemos ir un poco más allá, trabajar con SOA permite reutilizar los servicios existentes para construir otros, mejores o más complejos, de forma que podamos aprovechar el trabajo realizado anteriormente y no estar constantemente empezando desde cero. Pensar en servicios que pueden ser aprovechados por otros, permite realizar un mejor trabajo tanto dentro como fuera de tu organización.</p>
<p>Mira el siguiente gráfico para que veas los cambios que propone SOA en el desarrollo de aplicaciones.</p>
<p><a href="http://copstone.com/wp-content/uploads/2010/07/A_D_SOA.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="A_D_SOA" border="0" alt="A_D_SOA" src="http://copstone.com/wp-content/uploads/2010/07/A_D_SOA_thumb.png" width="622" height="354" /></a> </p>
<p>SOA es realmente un tema bastante amplio, por lo que sólo he escrito acerca de las generalidades de esta arquitectura, te recomiendo leer más, dado que SOA viene siendo usado actualmente, esta en auge, y con las herramientas que tienen los lenguajes de programación puedes implementar mejores servicios para tus aplicaciones.</p>
]]></content:encoded>
			<wfw:commentRss>http://copstone.com/2010/07/service-oriented-arquitecture/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Crear un Documento MSWord con C#</title>
		<link>http://copstone.com/2010/05/crear-un-documento-msword-con-c-sharp/</link>
		<comments>http://copstone.com/2010/05/crear-un-documento-msword-con-c-sharp/#comments</comments>
		<pubDate>Thu, 20 May 2010 17:20:00 +0000</pubDate>
		<dc:creator>Victor Parasi</dc:creator>
				<category><![CDATA[net]]></category>
		<category><![CDATA[Productividad]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Office]]></category>

		<guid isPermaLink="false">http://copstone.com/?p=1042</guid>
		<description><![CDATA[Cansado de realizar tu reportes en un archivo de texto? si ya te cansaste de que tu aplicación interactúe con NotePad, entonces este post es para tí]]></description>
			<content:encoded><![CDATA[<p>Al ser MS Word, uno de los procesadores de texto más usados, Visual Studio permite interactuar con MS Word, de forma que podamos crear y escribir un reporte utilizando esta aplicación.</p>
<p>Antes de empezar a analizar el código, diremos que Visual Studio 2008, permite crear proyectos del tipo Office; es decir, ya viene preparado para crear aplicaciones (Add-ins) no sólo con MS Word, sino con MS Excel, MS Outlook, de una forma bastante sencilla, pero no voy a usar esa opción. </p>
<p>Lo que voy a hacer es mediante un proyecto ClassLibrary, interactuar con el Assembly (Interop) que me permite trabajar con MS Word, como si fuera una clase mas. Este Assembly viene con Visual Studio 2008, pero si por alguna razón no lo tienes, te dejo este link: <a href="http://msdn.microsoft.com/es-es/library/15s06t57(VS.80).aspx">http://msdn.microsoft.com/es-es/library/15s06t57(VS.80).aspx</a></p>
<p>Bueno, empezaremos creando un proyecto del tipo ClassLibrary al cual le voy a agregar la siguiente referencia: Microsoft.Office.Interop.Word. Para MS Office 2007, la versión de este Assembly es la 12.0, para MS Office 2003, es la 11.0.</p>
<p>Luego que ya esta creado el proyecto ClassLibrary y hemos añadido la referencia antes indicada, debes de agregar este línea en el código de nuestra clase.</p>
<pre class="brush:csharp;auto-links:false;collapse:false;first-line:1;gutter:true;smart-tabs:true;wrap-lines:true;%SYNTAX_HIGHLIGHTER_CSHARP%">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Word = Microsoft.Office.Interop.Word; //Agrega esta línea</pre>
<p>Agregada la línea anterior, voy colocar un método a la clase del ClassLibrary, de forma que podamos: crear una instancia de una aplicación MSWord, agregarle un Documento para poder escribir y luego insertar texto en el documento.</p>
<p>Te dejo el código:</p>
<pre style="width: 646px; height: 724px" class="brush:csharp;auto-links:false;collapse:false;first-line:1;gutter:true;smart-tabs:true;wrap-lines:true;%SYNTAX_HIGHLIGHTER_CSHARP%">public class Reporte
{

        public void EscribirenunDocumentoWord()
        {
            //Objeto del Tipo Word Application
            Word.Application objWordApplication;
            //Objeto del Tipo Word Document
            Word.Document objWordDocument;
            // Objeto para interactuar con el Interop
            Object oMissing = System.Reflection.Missing.Value;

            //Creamos una instancia de una Aplicación Word.
            objWordApplication = new Word.Application();
            //A la aplicación Word, le añadimos un documento.
            objWordDocument = objWordApplication.Documents.Add(ref oMissing,
                                                             ref oMissing,
                                                             ref oMissing,ref oMissing );

            //Activamos el documento recien creado, de forma que podamos escribir en el
            objWordDocument.Activate();
            //Empezamos a escribir
            objWordApplication.Selection.TypeText(&quot;Este es un ejemplo desarrollado por &quot;);
            objWordApplication.Selection.TypeText(&quot;COPSTONE, esperamos que sea útil y &quot;);
            objWordApplication.Selection.TypeText(&quot; que te ayude a crear nuevas y  &quot;);
            objWordApplication.Selection.TypeText(&quot;mejores aplicaciones. &quot;);
            //Indicamos que el texto anterior es parte de un párrafo.
            objWordApplication.Selection.TypeParagraph();

            //Ahora veamos como cambiar el tipo y tamaño de la letra

            objWordApplication.Selection.Font.Name=&quot;Arial&quot; ; //Cambiamos el nombre
            objWordApplication.Selection.Font.Size= 19; //Cambiamos el tamaño
            //Alinearemos el texto que vamos a escribir al centro
            objWordApplication.Selection.ParagraphFormat.Alignment=
               Microsoft.Office.Interop.Word.WdParagraphAlignment.wdAlignParagraphCenter ;
            //Agregamos al texto
            objWordApplication.Selection.TypeText(&quot;Hecho por Copstone 2010&quot;);
            //Indicamos que el texto anterior es un párrafo
            objWordApplication.Selection.TypeParagraph();
            //Hace visible la Aplicacion para que veas lo que se ha escrito
            objWordApplication.Visible = true; 

        }</pre>
<p>Ahora, si quieres automatizar mas cosas como insertar tablas, imágenes, debes de empezar con leer el esquema del objeto MSWord, te dejo un link donde puedes encontrar mayor información: <a href="http://msdn.microsoft.com/en-us/library/kw65a0we(VS.80).aspx">http://msdn.microsoft.com/en-us/library/kw65a0we(VS.80).aspx</a></p>
<p>Espero que este post te sea de mucha ayuda y si tienes alguna duda, deja un comentario.</p>
]]></content:encoded>
			<wfw:commentRss>http://copstone.com/2010/05/crear-un-documento-msword-con-c-sharp/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Hola Mundo en Silverlight 4.0</title>
		<link>http://copstone.com/2010/05/hola-mundo-en-silverlight-4-0/</link>
		<comments>http://copstone.com/2010/05/hola-mundo-en-silverlight-4-0/#comments</comments>
		<pubDate>Fri, 07 May 2010 07:00:00 +0000</pubDate>
		<dc:creator>Victor Parasi</dc:creator>
				<category><![CDATA[net]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[Silverlight]]></category>

		<guid isPermaLink="false">http://copstone.com/?p=1039</guid>
		<description><![CDATA[Cuando de aplicaciones Web se trata, no debemos dejar de lado las animaciones o gráficos que podemos hacer desde nuestra aplicación. Silverlight es una herramienta de Microsoft que te ayudará a enriquecer tus aplicaciones Web, lee este post si te quieres iniciar en este mundo.]]></description>
			<content:encoded><![CDATA[<p>Con el lanzamiento de la nueva versión de Visual Studio y de .Net Framework 4.0, existe una novedad adicional: Silverlight 4.0</p>
<p>Para lo que no conocen de Silverlight, les puedo que esta herramienta es de Microsoft y es la propuesta que viene manejando esta compañía para crear aplicaciones web con mayores funciones multimedia, esto incluye videos, gráficos, animaciones, etc. Si, porque no decirlo, es la competencia de Adobe Flash. </p>
<p>En esta ocasión vamos a ver ejemplos acerca de Silverlight 4.0, para que veas lo sencillo que es esta herramienta, para tal efecto tengo instalado en mi PC, Visual Studio 2010 y <a href="http://www.microsoft.com/downloads/details.aspx?familyid=BF5AB940-C011-4BD1-AD98-DA671E491009&amp;displaylang=en">Silverlight 4.0 RC2</a>.</p>
<h3>Creando una Aplicación Silverlight 4.0</h3>
<p>Visual Studio 2010, tiene el mismo menú que sus versiones anteriores, por lo que accediendo a :</p>
<p><strong>File-&gt; New-&gt;Project</strong>, podemos acceder a la ventana con todos los tipos de proyecto que podemos crear, en esta ocasión seleccionaré Silverlight, en Installed Templates y Silverlight Application como tipo de apliación. Ambos siempre en C#. Te dejo la imagen para que te orientes:</p>
<p><a href="http://copstone.com/wp-content/uploads/2010/05/image.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://copstone.com/wp-content/uploads/2010/05/image_thumb.png" width="612" height="356" /></a> </p>
<p>Luego de pulsar el botón de OK, accedemos a la siguiente ventana, donde podemos escoger la versión de Silverlight que vamos a utilizar. En este punto es necesaria una aclaración. Visual Studio 2010, trae por defecto Silverlight 3, pero instalando las Silverligth 4.0 RC2, podemos trabajar con ambas versiones. </p>
<p><a href="http://copstone.com/wp-content/uploads/2010/05/image1.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://copstone.com/wp-content/uploads/2010/05/image_thumb1.png" width="404" height="332" /></a> </p>
</p>
<p>Damos OK y listo, obtenemos lo siguiente:</p>
<p><a href="http://copstone.com/wp-content/uploads/2010/05/image2.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://copstone.com/wp-content/uploads/2010/05/image_thumb2.png" width="635" height="285" /></a> </p>
<p>En la figura podemos observar 3 secciones:</p>
<ul>
<li>Sobre la derecha de la imagen, tenemos nuestro conocido Solution Explorer&#160; con dos proyectos. Uno con el componente Silverlight (donde se encuentran archivos con extensión xaml) y otro una aplicación Web, donde se incrustará el componente y podrá ser visualizado. </li>
<li>Sobre la parte central, tenemos nuestra área de trabajo (Layout), haciendo una analogía con una&#160; Web Application, vendría a ser nuestro formulario. </li>
<li>En la parte inferior, tenemos el código del formulario, esta sección se va actualizando conforme vamos agregando componentes o modificando opciones. </li>
</ul>
<h3>Colocando un Label</h3>
<p>Como puedes apreciar, trabajar con una Aplicación Silverlight, no va a ser nada del otro mundo. Es más, para cumplir con el objetivo del post,&#160; veremos que el toolbox es muy parecido al que ya estamos acostumbrado y existen casi los mismos controles. Voy a utilizar un Label y lo colocaré en mi área de trabajo.</p>
<p><a href="http://copstone.com/wp-content/uploads/2010/05/image3.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://copstone.com/wp-content/uploads/2010/05/image_thumb3.png" width="253" height="370" /></a> </p>
<p>Terminando de Colocar el Label, podemos apreciar que este aparece con dos flechas, las cuales te ayudarán a ubicar mejor el componente en la región que desees.</p>
<p><a href="http://copstone.com/wp-content/uploads/2010/05/image4.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://copstone.com/wp-content/uploads/2010/05/image_thumb4.png" width="518" height="173" /></a> </p>
</p>
<p>Y en la parte inferior, como puedes apreciar, se ha actualizado el código.</p>
<p><a href="http://copstone.com/wp-content/uploads/2010/05/image5.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://copstone.com/wp-content/uploads/2010/05/image_thumb5.png" width="636" height="73" /></a></p>
<p>Para trabajar con las propiedades del componente, lo puedes hacer de la forma tradicional: Accediendo a Properties (con F4, de manera rápida) y allí cambiar la propiedad necesaria. Otra forma de cambiar el valor de las propiedades es hacerlo a través del código, agregando el nombre la propiedad y el valor. Esto es lo que voy a hacer yo.</p>
<div id="ts75113243" class="tabsheet_h cfix">
<p id="ts75113243_1" class="tab_h">Código XAML</p>
<p id="ts75113243_2" class="tab_h">Resultado</p>
</p></div>
<div id="ts75113243_1c" class="tab_c ts75113243">
<pre style="width: 566px; height: 120px" class="brush:xml;auto-links:false;collapse:false;first-line:1;gutter:true;smart-tabs:true;wrap-lines:true;%SYNTAX_HIGHLIGHTER_XML%">&lt;Grid x:Name=&quot;LayoutRoot&quot; Background=&quot;White&quot;&gt;
        &lt;sdk:Label Height=&quot;28&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;62,49,0,0&quot;
        Name=&quot;Label1&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;120&quot;
        Content=&quot;Hola Mundo&quot;/&gt;
    &lt;/Grid&gt;</pre>
</div>
<div id="ts75113243_2c" class="tab_c ts75113243">
<p>&#160;<a href="http://copstone.com/wp-content/uploads/2010/05/image6.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://copstone.com/wp-content/uploads/2010/05/image_thumb6.png" width="614" height="390" /></a> </p>
</div>
<p>Como podrás ver, le he colocado al código al ya existente, Content=&quot;Hola Mundo&quot;.</p>
<p>Veamos que más podemos hacer:</p>
<div id="ts95113412" class="tabsheet_h cfix">
<p id="ts95113412_1" class="tab_h">Código XAML</p>
<p id="ts95113412_2" class="tab_h">Resultado</p>
</div>
<div id="ts95113412_1c" class="tab_c ts95113412">
<pre style="width: 541px; height: 120px" class="brush:xml;auto-links:false;collapse:false;first-line:1;gutter:true;smart-tabs:true;wrap-lines:true;%SYNTAX_HIGHLIGHTER_XML%">&lt;Grid x:Name=&quot;LayoutRoot&quot; Background=&quot;White&quot;&gt;
        &lt;sdk:Label Height=&quot;28&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;62,49,0,0&quot;
        Name=&quot;Label1&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;120&quot;
        Content=&quot;Hola Mundo&quot;FontFamily=&quot;Arial Black&quot; FontSize=&quot;20&quot;
	Background=&quot;Salmon&quot; Foreground=&quot; Blue&quot;/&gt;/&gt;
    &lt;/Grid&gt;</pre>
</div>
<div id="ts95113412_2c" class="tab_c ts95113412">
<p>&#160;<a href="http://copstone.com/wp-content/uploads/2010/05/image7.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://copstone.com/wp-content/uploads/2010/05/image_thumb7.png" width="591" height="402" /></a></p>
</div>
<p>&#160;</p>
<p>Si analizas el código, puedes apreciar, que he realizado cambios sobre la fuente: Familia, Size, Background y Foreground.</p>
<p><a href="http://copstone.com/wp-content/uploads/2010/05/image8.png"></a></p>
<p>Una aclaración necesaria, el color por defecto del Layout, es White, eso dice en la primera línea del código que estoy colocando:</p>
<pre style="width: 548px; height: 47px" class="brush:xml;auto-links:false;collapse:false;first-line:1;gutter:true;smart-tabs:true;wrap-lines:true;%SYNTAX_HIGHLIGHTER_XML%">&lt;Grid x:Name=&quot;LayoutRoot&quot; Background=&quot;White&quot;&gt;</pre>
<p>Ahora,si cambio este valor puedo tener este efecto:</p>
<div id="ts79113536" class="tabsheet_h cfix">
<p id="ts79113536_1" class="tab_h">Código XAML</p>
<p id="ts79113536_2" class="tab_h">Resultado</p>
</div>
<div id="ts79113536_1c" class="tab_c ts79113536">
<pre style="width: 561px; height: 135px" class="brush:xml;auto-links:false;collapse:false;first-line:1;gutter:true;smart-tabs:true;wrap-lines:true;%SYNTAX_HIGHLIGHTER_XML%">&lt;Grid x:Name=&quot;LayoutRoot&quot; Background=&quot;Salmon&quot;&gt;
        &lt;sdk:Label Height=&quot;30&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;62,49,0,0&quot;
	Name=&quot;Label1&quot; VerticalAlignment=&quot;Top&quot;
	Width=&quot;132&quot; Content=&quot;Hola Mundo&quot; FontFamily=&quot;Arial Black&quot;
        FontSize=&quot;20&quot; Foreground=&quot; Blue&quot;/&gt;
    &lt;/Grid&gt;</pre>
</div>
<div id="ts79113536_2c" class="tab_c ts79113536">
<p>&#160;<a href="http://copstone.com/wp-content/uploads/2010/05/image9.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://copstone.com/wp-content/uploads/2010/05/image_thumb8.png" width="558" height="357" /></a> </p>
</div>
<p>&#160;</p>
</p>
</p>
</p>
<p>Espero que a partir de ahora puedas involucrarte más en el mundo de las aplicaciones Web, utilizando Silverlight como herramienta para desarrollarlas.</p>
]]></content:encoded>
			<wfw:commentRss>http://copstone.com/2010/05/hola-mundo-en-silverlight-4-0/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

