<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://geeks.ms/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>El armario "ropero"</title><link>http://geeks.ms/blogs/mropero/default.aspx</link><description>Divagaciones de un armario cualquiera</description><dc:language /><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Mutex vs Semaphore</title><link>http://geeks.ms/blogs/mropero/archive/2009/11/24/mutex-vs-semaphore.aspx</link><pubDate>Tue, 24 Nov 2009 09:41:18 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:161151</guid><dc:creator>Mario Ropero</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/mropero/rsscomments.aspx?PostID=161151</wfw:commentRss><comments>http://geeks.ms/blogs/mropero/archive/2009/11/24/mutex-vs-semaphore.aspx#comments</comments><description>&lt;p&gt;El otro día estaba leyendo y encontré un sitio que exponía algunas preguntas que hacía Google en su entrevista de trabajo y ví una de ellas y me pareció curiosa (sobre todo porque creía saber la respuesta) y era “&lt;em&gt;¿Diferencia entre Mutex y Semaphore?&lt;/em&gt;” y como ahora estoy a ver si aprendo un poco de concurrencia y esas cosicas me dije, esta es fácil a ver si soy capaz de explicarla de una forma sencilla.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Lo primero decir es que tanto el Mutex como el Semaphore son herramientas para controlar/bloquear (el nombre correcto es sincronizar, pero vamos…) el acceso a recursos desde nuestros hilillos. Y creo que lo mejor es contar un ejemplo y no de código.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Imaginemos (o supongamos) que tenemos 3 cajas que queremos utilizar, cuando una persona viene a utilizar una caja, se la lleva y entonces sólo quedan 2 cajas, cuando ha terminado de utilizarla la deja y vuelven a quedar 3 cajas, si vienen 3 personas y cogen las 3 cajas, el próximo que venga tendrá que esperar a que alguna de las personas termine con la caja y la devuelva. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Buenos si a eso le ponemos que las cajas son recursos y las personas son hilos, eso sería, más o menos, el funcionamiento de un Semaphore con Count = 3. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Creo que es bastante sencilo, y bien la pregunta ¿qué es el Mutex?, pues la respuestas sencilla sería decir que un Mutex es un Semaphore con Count = 1.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Y listo, evidentemente esto es algo más complejo pero creo que eso sería una descripción bastante sencilla y aproximada.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Os dejo las direcciones de la documentación del msdn para que veáis ejemplos, aquí el &lt;a href="http://msdn.microsoft.com/en-us/library/hw29w7t1.aspx"&gt;Mutex&lt;/a&gt; y aquí el &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.semaphore.aspx"&gt;Semaphore&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Un saludo y hasta la próxima,&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Mario Ropero.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=161151" width="1" height="1"&gt;</description></item><item><title>[FW 3.5] Obtener los miembros recursivamente de un grupo en directorio activo</title><link>http://geeks.ms/blogs/mropero/archive/2009/11/17/fw-3-5-obtener-los-miembros-recursivamente-de-un-grupo-en-directorio-activo.aspx</link><pubDate>Tue, 17 Nov 2009 20:00:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:160682</guid><dc:creator>Mario Ropero</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/mropero/rsscomments.aspx?PostID=160682</wfw:commentRss><comments>http://geeks.ms/blogs/mropero/archive/2009/11/17/fw-3-5-obtener-los-miembros-recursivamente-de-un-grupo-en-directorio-activo.aspx#comments</comments><description>&lt;p&gt;Hola a todos, con el FW 3.5 hay una opción para recoger todos los miembros de un grupo en modo recursivo, así que ya se acabó de ir buscando los miembros del grupo y ver si tenía a su vez miembros y todo el rato lo mismo.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Es que estos chicos de .NET son muuuuuy listos. Os pongo un ejemplillo pero es sumamente sencillo.&lt;/p&gt;  &lt;p&gt;El espacio de nombres a usar es &lt;em&gt;System.DirectoryServices.AccountManagement&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; nombreGrupo = &lt;span style="color:#006080;"&gt;&amp;quot;grupo&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; nombreDominio = &lt;span style="color:#006080;"&gt;&amp;quot;dominio&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (PrincipalContext ctx = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; PrincipalContext(ContextType.Domain, nombreDominio))&lt;br /&gt;{&lt;br /&gt;    GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, nombreGrupo);&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (grp != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;    {&lt;br /&gt;        &lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (Principal p &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; grp.GetMembers(&lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;))&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine(p.Name); &lt;br /&gt;        }&lt;br /&gt;        grp.Dispose();&lt;br /&gt;    }                &lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Y ya está, la gracia está en el &lt;em&gt;GetMembers(true). &lt;/em&gt;Una cosa a tener en cuenta es que si el usuario que ejecuta este código no tiene permisos para poder ver un grupo dará un error de “Member not found”, así que es necesario que tenga permisos por lo menos de visualización.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Este post es corto, y creo que va a ser una serie de post para hacer cosas sencillas, porque creo que cuando estoy mucho tiempo sin desarrollar en algo, al final las cosas más sencillas o simples son las que más buscamos, o por lo menos en mi caso que soy un rato zote.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Un saludo a todos.&lt;/p&gt;

&lt;p&gt;“Ar” Mario Ropero.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=160682" width="1" height="1"&gt;</description></item><item><title>System.Transactions y concurrencia</title><link>http://geeks.ms/blogs/mropero/archive/2009/11/03/system-transactions-y-concurrencia.aspx</link><pubDate>Tue, 03 Nov 2009 10:00:28 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:159840</guid><dc:creator>Mario Ropero</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/mropero/rsscomments.aspx?PostID=159840</wfw:commentRss><comments>http://geeks.ms/blogs/mropero/archive/2009/11/03/system-transactions-y-concurrencia.aspx#comments</comments><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p align="justify"&gt;Hola a todos, llevo bastante tiempo desconectado y es que el verano me ha sentado mal y estoy muy perruno, pero bueno vamos a ver si podemos hacer algo para remediarlo. Hace tiempo conté un problemita que me surgió con los TransactionScope y su abuso. &lt;/p&gt;  &lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;  &lt;p align="justify"&gt;Esta vez el problema estaba en que un proceso hacía una operación y en un momento llamaba a un hilo en background para procesar otro trabajo, pero todo tenía que estar dentro de la misma transacción o al menos que sólo se hiciese commit si todos los procesos acababan bien. &lt;/p&gt;  &lt;p align="justify"&gt;Bueno pues ahí empezaron mis problemas, porque cuando tú creas un TransactionScope por defecto el crea una transacción (ambient transaction que se llama) y la almacena en el Thread Local Storage (lo que viene siendo el TLS) del hilo en uso y esto hace que no se propague a los nuevos hilos que se generan. Y buscando por la red encontré el whitepaper de un “peaso” de crack que ya me dijeron en su tiempo, el gran Juval Lowy y expone la solución para estos problemas.&lt;/p&gt;  &lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;  &lt;p align="justify"&gt;Os lo pongo aquí, pero realmente creo que es mejor que os bajéis el &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=AAC3D722-444C-4E27-8B2E-C6157ED16B15&amp;amp;displaylang=en"&gt;whitepaper&lt;/a&gt; y le echéis un vistazo que no es nada pesado y la verdad explica muy bien cómo funciona todo y el LTM y bueno, clarifica bastante…&lt;/p&gt;  &lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;  &lt;p align="justify"&gt;En el tema de la concurrencia, os pongo un ejemplo de la clase que se ejecutaría sobre uno de los hilos generados&lt;/p&gt;  &lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Obrero&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Trabaja(DependentTransaction transaccion)&lt;br /&gt;    {&lt;br /&gt;        Thread thread = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Thread(Metodo);&lt;br /&gt;        thread.Start(transaccion);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Metodo(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; transaccion)&lt;br /&gt;    {&lt;br /&gt;        DependentTransaction tran = transaccion &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; DependentTransaction;&lt;br /&gt;&lt;br /&gt;        Transaction antiguaTransaccion = Transaction.Current;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;try&lt;/span&gt;&lt;br /&gt;        {&lt;br /&gt;            Transaction.Current = tran;&lt;br /&gt;&lt;br /&gt;            Debug.WriteLine(&lt;span style="color:#006080;"&gt;&amp;quot;Esto tiene que estar dentro de una transacción... o algo similar :)&amp;quot;&lt;/span&gt;);&lt;br /&gt;            &lt;br /&gt;            tran.Complete();&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;finally&lt;/span&gt;&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color:#008000;"&gt;//Liberamos la transaccion que hemos pasado y volvemos a poner la transacción a la antigua&lt;/span&gt;&lt;br /&gt;            tran.Dispose();&lt;br /&gt;            Transaction.Current = antiguaTransaccion;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p align="justify"&gt;Aquí lo único ha observar, es que&amp;#160; a la clase se le pasa un objeto DepedentTransaction y es el que usa para hacer el Complete() una vez hecho el trabajo que tenga que hacer, en este caso un importantísimo Debug.WriteLine.&lt;/p&gt;

&lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;

&lt;p align="justify"&gt;Desde el “padre” para invocar a esto sería un código similar a esto&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (TransactionScope scope = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; TransactionScope())&lt;br /&gt;{ &lt;br /&gt;    &lt;span style="color:#008000;"&gt;//Vamos a recoger la transacción actual y generar un dependentTransaction a través&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;//del método DependentClone()&lt;/span&gt;&lt;br /&gt;    DependentTransaction transaccion = Transaction.Current.DependentClone(DependentCloneOption.BlockCommitUntilComplete);&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color:#008000;"&gt;//Aquí llamo a la clase que generar el hilo y hace otro trabajo transaccional&lt;/span&gt;&lt;br /&gt;    Obrero obrero = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Obrero();&lt;br /&gt;&lt;br /&gt;    obrero.Trabaja(transaccion);&lt;br /&gt;&lt;br /&gt;    Debug.WriteLine(&lt;span style="color:#006080;"&gt;&amp;quot;El papi hace cualquiero tipo de trabajo transaccional&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;//Este Complete() significa que en este instante se ejecutará el Commit de los hijos y del padre&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;//debido a la opción de DependentCloneOption que está a BlockCommitUntilComplete, esto quiere decir&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;//que no se hará ningún commit de los &amp;quot;hijos&amp;quot; hasta que el padre haga el Complete()&lt;/span&gt;&lt;br /&gt;    scope.Complete();&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p align="justify"&gt;Bueno aquí las cosas importantes son el método &lt;em&gt;DependentClone &lt;/em&gt;de la transacción actual y la opción de DependentCloneOption, lo demás no es más que pasarle a la clase que hemos creado antes, la transacción generada y que trabaje sobre ella.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;Las distintas opciones de DependentCloneOption&lt;/h4&gt;

&lt;p align="justify"&gt;Esto es un enumerado que tiene dos opciones, BlockCommitUntilComplete y RollbackIfNotComplete. &lt;/p&gt;

&lt;p align="justify"&gt;La opción BlockCommitUntilComplete, hace que no se ejecuten los commit de las transacciones dependientes hasta que la transacción “padre” haga el Complete(), esto en la practica hace que cuando en una transacción dependiente se haga un Complete(), la transacción se marca como “lista para hacer commit” pero no se ejecuta.&lt;/p&gt;

&lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;

&lt;p align="justify"&gt;La opción RollbackIfNotComplete, hace que si el “padre” ejecuta el Complete() y existe alguna transacción dependiente que todavía no haya hecho un Complete() se generará una TransactionAbortedException, y además el hilo hijo seguirá trabajando para nada porque la transacción ya está abortada.&lt;/p&gt;

&lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;

&lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;

&lt;p align="justify"&gt;La verdad es que esto del System.Transactions tiene bastante miga, seguiré investigando cositas que aunque es una tecnología bastante antigua ya, todavía sigue dando mucha guerra en los proyectos porque no se utiliza correctamente, y por cierto os vuelvo a recomendar a todos leeros el whitepaper de Juval Lowy que mola…&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Un saludo a todos.&lt;/p&gt;

&lt;p&gt;Mario Ropero.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=159840" width="1" height="1"&gt;</description></item><item><title>Compilar en tiempo de ejecución</title><link>http://geeks.ms/blogs/mropero/archive/2009/10/08/compilar-en-tiempo-de-ejecuci-243-n.aspx</link><pubDate>Thu, 08 Oct 2009 13:30:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:157622</guid><dc:creator>Mario Ropero</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/mropero/rsscomments.aspx?PostID=157622</wfw:commentRss><comments>http://geeks.ms/blogs/mropero/archive/2009/10/08/compilar-en-tiempo-de-ejecuci-243-n.aspx#comments</comments><description>&lt;p align="justify"&gt;Hola a todos, seguro que muchos de vosotros ya sabéis de que va todo esto, pero es que es una de las cosas que más gracia me hizo cuando descubrí cómo hacerlo. Vamos a ver cómo gracias a una librería muy maja (&lt;a href="http://msdn.microsoft.com/en-us/library/system.codedom.aspx"&gt;System.CodeDom&lt;/a&gt;) podemos compilar en tiempo de ejecución y gracias a la reflexión (ya sabéis que es la raíz de todo mal) podemos ejecutarlo.&lt;/p&gt;  &lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;  &lt;p align="justify"&gt;El uso que se le puede dar a esto es prácticamente ilimitado aunque no es tan fácil de ver (al menos en mí caso), así que me encantaría que me dijeseis para qué lo habéis usado para hacerme una idea, en mí caso yo lo tuve que usar para permitir que ciertos usuarios bastante avanzados pudieran meter validaciones complejas sobre campos y se ejecutasen al momento, vamos para hacer un generador de fórmulas y cosas así está muy bien.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Bueno os pongo un ejemplito para que veáis lo fácil que es (la verdad es que los chicos de .NET son unos tipos muy listos).&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;La función que genera una clase en tiempo de ejecución que tiene un método que ejecuta un “Hola Mundo!”&lt;/p&gt;  &lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; CreaYCompilaHolaMundoClass()&lt;br /&gt;        {&lt;br /&gt;            CompilerParameters cp = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; CompilerParameters();&lt;br /&gt;            cp.ReferencedAssemblies.Add(&lt;span style="color:#006080;"&gt;&amp;quot;system.dll&amp;quot;&lt;/span&gt;);&lt;br /&gt;            cp.ReferencedAssemblies.Add(&lt;span style="color:#006080;"&gt;&amp;quot;system.data.dll&amp;quot;&lt;/span&gt;);&lt;br /&gt;            cp.ReferencedAssemblies.Add(&lt;span style="color:#006080;"&gt;&amp;quot;system.xml.dll&amp;quot;&lt;/span&gt;);&lt;br /&gt;            cp.ReferencedAssemblies.Add(&lt;span style="color:#006080;"&gt;&amp;quot;system.windows.forms.dll&amp;quot;&lt;/span&gt;);&lt;br /&gt;            &lt;br /&gt;            cp.GenerateExecutable = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;br /&gt;            cp.GenerateInMemory = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;            StringBuilder code = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; StringBuilder();&lt;br /&gt;            code.Append(&lt;span style="color:#006080;"&gt;&amp;quot;using System; \n&amp;quot;&lt;/span&gt;);&lt;br /&gt;            code.Append(&lt;span style="color:#006080;"&gt;&amp;quot;using System.Windows.Forms; \n&amp;quot;&lt;/span&gt;);&lt;br /&gt;            code.Append(&lt;span style="color:#006080;"&gt;&amp;quot;using System.Data; \n&amp;quot;&lt;/span&gt;);&lt;br /&gt;            code.Append(&lt;span style="color:#006080;"&gt;&amp;quot;using System.Xml; \n&amp;quot;&lt;/span&gt;);&lt;br /&gt;            code.Append(&lt;span style="color:#006080;"&gt;&amp;quot;using System.Reflection; \n&amp;quot;&lt;/span&gt;);&lt;br /&gt;            code.Append(&lt;span style="color:#006080;"&gt;&amp;quot;namespace Prueba.Compilador { \n&amp;quot;&lt;/span&gt;);&lt;br /&gt;            code.AppendFormat(&lt;span style="color:#006080;"&gt;&amp;quot;  public class {0} &amp;quot;&lt;/span&gt;, &lt;span style="color:#006080;"&gt;&amp;quot;HolaMundo&amp;quot;&lt;/span&gt;);&lt;br /&gt;            code.Append(&lt;span style="color:#006080;"&gt;&amp;quot;{ &amp;quot;&lt;/span&gt;);&lt;br /&gt;            &lt;span style="color:#008000;"&gt;//Clases de apoyo&lt;/span&gt;&lt;br /&gt;            &lt;span style="color:#008000;"&gt;//GetValue a string&lt;/span&gt;&lt;br /&gt;            code.Append(&lt;span style="color:#006080;"&gt;&amp;quot; public void HazTuTrabajo() \n&amp;quot;&lt;/span&gt;);&lt;br /&gt;            code.Append(&lt;span style="color:#006080;"&gt;&amp;quot;  {&amp;quot;&lt;/span&gt;);&lt;br /&gt;            code.Append(&lt;span style="color:#006080;"&gt;&amp;quot; MessageBox.Show(\&amp;quot;Hola mundo\&amp;quot;);&amp;quot;&lt;/span&gt;);&lt;br /&gt;            code.Append(&lt;span style="color:#006080;"&gt;&amp;quot; }\n&amp;quot;&lt;/span&gt;);           &lt;br /&gt;           &lt;br /&gt;            code.Append(&lt;span style="color:#006080;"&gt;&amp;quot;} }&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;            CompilerResults cr = CodeDomProvider.CreateProvider(&lt;span style="color:#006080;"&gt;&amp;quot;C#&amp;quot;&lt;/span&gt;).CompileAssemblyFromSource(cp, code.ToString());&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (cr.Errors.HasErrors)&lt;br /&gt;            {&lt;br /&gt;                StringBuilder error = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; StringBuilder();&lt;br /&gt;                error.Append(&lt;span style="color:#006080;"&gt;&amp;quot;Error al compilar: &amp;quot;&lt;/span&gt;);&lt;br /&gt;                &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (CompilerError err &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; cr.Errors)&lt;br /&gt;                {&lt;br /&gt;                    error.AppendFormat(&lt;span style="color:#006080;"&gt;&amp;quot;{0}\n&amp;quot;&lt;/span&gt;, err.ErrorText);&lt;br /&gt;                }&lt;br /&gt;                &lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Exception(&lt;span style="color:#006080;"&gt;&amp;quot;Error al compilar: &amp;quot;&lt;/span&gt; + error.ToString());&lt;br /&gt;            }&lt;br /&gt;            Assembly a = cr.CompiledAssembly;&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; a.CreateInstance(&lt;span style="color:#006080;"&gt;&amp;quot;Prueba.Compilador.HolaMundo&amp;quot;&lt;/span&gt;);&lt;br /&gt;        }&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt; Lo primero importante es que necesita el using del System.CodeDom.Compiler. Luego cosas a destacar, ReferencedAssemblies son las dlls que queremos referenciar desde nuestro código generado (en el ejemplo he puesto varios aunque no se necesitan todos), en este caso no se genera una dll física si no que está compilada en memoria.&lt;/p&gt;

&lt;p&gt;Después escribimos el código que queramos que tenga (hay que tener un poco de cuidado con las llaves de apertura y cierre) y la línea de CompilerResults….. es la importante. Después de eso se genera un Assembly (System.Reflection) y se devuelve una instancia…&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Para ejecutar lo que hemos creado sería algo similar a esto&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; _comp = CreaYCompilaHolaMundoClass();&lt;br /&gt;MethodInfo mi = _comp.GetType().GetMethod(&lt;span style="color:#006080;"&gt;&amp;quot;HazTuTrabajo&amp;quot;&lt;/span&gt;);&lt;br /&gt;mi.Invoke(_comp, &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;);&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt; Y poco más… evidentemente esto se puede complicar lo que queramos, pasando parámetros y demás… como os dije antes se abren muchas, muchísimas puertas aunque hay veces que es complicado verle la utilidad.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p align="justify"&gt;Por cierto, yo no opino que usar reflexión sea malo, siempre y cuando sea usada correctamente (creo que hay muchas discusiones sobre esto pero algún día me gustaría escribir sobre ello) la reflexión mola y mola mucho.&lt;/p&gt;

&lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;

&lt;p align="justify"&gt;Un saludo y hasta la próxima.&lt;/p&gt;

&lt;p align="justify"&gt;Mario Ropero.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=157622" width="1" height="1"&gt;</description></item><item><title>[WCF] DataContractSerializer y la propiedad IsReference. .NET 3.5 SP1</title><link>http://geeks.ms/blogs/mropero/archive/2009/09/29/wcf-datacontractserializer-y-la-propiedad-isreference-net-3-5-sp1.aspx</link><pubDate>Tue, 29 Sep 2009 18:00:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:156979</guid><dc:creator>Mario Ropero</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/mropero/rsscomments.aspx?PostID=156979</wfw:commentRss><comments>http://geeks.ms/blogs/mropero/archive/2009/09/29/wcf-datacontractserializer-y-la-propiedad-isreference-net-3-5-sp1.aspx#comments</comments><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Hola a todos, siguiendo al hilo de mi &lt;a href="http://geeks.ms/blogs/mropero/archive/2009/09/21/wcf-vuelta-a-la-realidad-y-jugando-con-el-datacontractserializer.aspx"&gt;anterior post&lt;/a&gt; y haciendo caso a un &lt;a href="http://geeks.ms/blogs/unai/"&gt;señor&lt;/a&gt; que de esto sabe un rato, se puede pasar por referencia los objetillos sin necesidad de generar un behavior especial, simplemente con una propiedad del atributo DataContract.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Sigo pensando exactamente lo mismo que antes, que esto, aunque solucione muchos problemas es posible que enmascare un desconocimiento de fondo por parte de los desarrolladores del proyecto, y que las cosas dejen de funcionar correctamente porque esto está o no aplicado.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Pero bueno al lío, que esto es rápido y sencillo.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;Clase que NO se pasa por referencia&lt;/h4&gt;  &lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;[DataContract]&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Persona&lt;br /&gt;{&lt;br /&gt;    [DataMember]&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Nombre {get;set;}&lt;br /&gt;&lt;br /&gt;    [DataMember]&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Apellidos {get;set;}&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Esto es un DataContract normal y corriente.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;Clase que SI se pasa por referencia&lt;/h4&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;[DataContract(IsReference = &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;)]&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Persona&lt;br /&gt;{&lt;br /&gt;    [DataMember]&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Nombre {get;set;}&lt;br /&gt;&lt;br /&gt;    [DataMember]&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Apellidos {get;set;}&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Como podéis observar es mucho más sencillo ahora. Lo único es que es necesario tener instalado el SP1 del framework 3.5.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Muchas gracias a Unai por indicarnos el camino….&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Hasta la próxima.
  &lt;p&gt;&amp;#160;&lt;/p&gt;

  &lt;p&gt;Mario Ropero.&lt;/p&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=156979" width="1" height="1"&gt;</description></item><item><title>[WCF] Vuelta a la realidad,… y jugando con el DataContractSerializer</title><link>http://geeks.ms/blogs/mropero/archive/2009/09/21/wcf-vuelta-a-la-realidad-y-jugando-con-el-datacontractserializer.aspx</link><pubDate>Mon, 21 Sep 2009 12:00:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:156197</guid><dc:creator>Mario Ropero</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/mropero/rsscomments.aspx?PostID=156197</wfw:commentRss><comments>http://geeks.ms/blogs/mropero/archive/2009/09/21/wcf-vuelta-a-la-realidad-y-jugando-con-el-datacontractserializer.aspx#comments</comments><description>&lt;p&gt;Hola a todos!!!!, han pasado muchas semanas sin que haya actualizado el blog, de hecho ni me he acercado a él. Necesitaba desconectar y vaya que si lo he hecho… :). Pero todo se acaba, así que aquí vuelvo a soltar rollazos a troche y moche (tampoco muchos, que esto de escribir cansa…). &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Uno de mis mayores problemas que he encontrado cuando se trabaja con un patrón proxy (como Remoting, WCF,…) es que mucha gente no tiene claro dónde van sus objetos y cómo se pasan los valores por referencia, por valor, etc… Y se escucha mucho eso de…”He pasado mi clase &lt;em&gt;loquesea &lt;/em&gt;y cuando actualizo en el servidor su valor, no me lo devuelve cambiado…”&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Debo deciros que a mí también me costó lo suyo (uno que es lento…), pero bueno es bastante normal que esto ocurra, y también es normal que haya formas de evitar esto, por ejemplo en Remoting había que poner explícitamente el “ref” en la variable y el se encargaba de mantener el cambio y devolverlo. &lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Pues estuve buscando algo similar para utilizar en WCF, y encontré que si usamos el DataContractSerializer (el serializador que se usa por defecto en WCF), tenemos una opción parecida aunque un poco más compleja de elaborar, se hace a través de OperationBehavior y decoradores de métodos.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;Generamos un DataContractSerializerOperationBehavior&lt;/h4&gt;  &lt;p&gt;Creamos una clase que herede de “DataContractSerializarOperationBehavior”, este es el behavior que luego aplicaremos a través del decorador. &lt;/p&gt;  &lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; SerializadorConReferencias : DataContractSerializerOperationBehavior&lt;br /&gt;   {&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; SerializadorConReferencias(OperationDescription operationDescription) &lt;br /&gt;        : &lt;span style="color:#0000ff;"&gt;base&lt;/span&gt;(operationDescription) &lt;br /&gt;       { }&lt;br /&gt;&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; XmlObjectSerializer CreateSerializer(Type type, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; name, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; ns, IList&amp;lt;Type&amp;gt; knownTypes)&lt;br /&gt;       {&lt;br /&gt;           &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; CreateDataContractSerializer(type, name, ns, knownTypes);&lt;br /&gt;       } &lt;br /&gt;&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; XmlObjectSerializer CreateDataContractSerializer(Type type, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; name, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; ns, IList&amp;lt;Type&amp;gt; knownTypes)&lt;br /&gt;       {&lt;br /&gt;           &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; CreateDataContractSerializer(type, name, ns, knownTypes);&lt;br /&gt;       } &lt;br /&gt;&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; XmlObjectSerializer CreateSerializer(Type type, XmlDictionaryString name, XmlDictionaryString ns, IList&amp;lt;Type&amp;gt; knownTypes)&lt;br /&gt;       {&lt;br /&gt;           &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; DataContractSerializer(type, name, ns, knownTypes,&lt;br /&gt;               2147483647 &lt;span style="color:#008000;"&gt;/* En plan bruto... */&lt;/span&gt;,&lt;br /&gt;               &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.IgnoreExtensionDataObject,&lt;br /&gt;               &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt; &lt;span style="color:#008000;"&gt;/*Aquí esta el cambio*/&lt;/span&gt;,&lt;br /&gt;               &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.DataContractSurrogate);&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;El caso está en el último CreateSerializer al que ponemos a &lt;em&gt;true&lt;/em&gt; la propiedad de “PreserveReferences”. Usando este serializador en vez del de por defecto ya lo tendríamos, pero queda más elegante si usamos un decorador de métodos y así decidimos los métodos que queremos que lo usen y los que no.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;Generamos un decorador que extienda IOperationBehavior&lt;/h4&gt;

&lt;p&gt;Para crear un decorador debemos heredar de Attribute y además en este caso debemos implementar el interfaz IOperationBehavior para poder aplicar este behavior en la operación (Método) que deseemos.&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; ConReferenciasDec : Attribute, IOperationBehavior&lt;br /&gt;   {&lt;br /&gt;       &lt;span style="color:#cc6633;"&gt;#region&lt;/span&gt; IOperationBehavior Members&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; AddBindingParameters(OperationDescription description, BindingParameterCollection parameters)&lt;br /&gt;       {&lt;br /&gt;       } &lt;br /&gt;&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; ApplyClientBehavior(OperationDescription description, ClientOperation proxy)&lt;br /&gt;       {&lt;br /&gt;           IOperationBehavior innerBehavior = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SerializadorConReferencias(description);&lt;br /&gt;           innerBehavior.ApplyClientBehavior(description, proxy);&lt;br /&gt;       } &lt;br /&gt;&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; ApplyDispatchBehavior(OperationDescription description, DispatchOperation dispatch)&lt;br /&gt;       {&lt;br /&gt;           IOperationBehavior innerBehavior = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SerializadorConReferencias(description);&lt;br /&gt;           innerBehavior.ApplyDispatchBehavior(description, dispatch);&lt;br /&gt;       } &lt;br /&gt;&lt;br /&gt;       &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Validate(OperationDescription description)&lt;br /&gt;       {&lt;br /&gt;       } &lt;br /&gt;&lt;br /&gt;       &lt;span style="color:#cc6633;"&gt;#endregion&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Aquí lo único a destacar es que tenemos que aplicar el behavior en el cliente y en el servidor. Ahora sólo nos quedaría utilizarlo.&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;interface&lt;/span&gt; IService&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;    [OperationContract]&lt;br /&gt;    [ConReferenciaDec]&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; DoSomething(ComplexType algo);&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;h4&gt;&amp;#160;&lt;/h4&gt;

&lt;h4&gt;Conclusiones&lt;/h4&gt;

&lt;p&gt;WCF mola mucho y se pueden hacer muchísimas cosas de una forma más o menos sencilla. En este caso en particular yo no estoy muy de acuerdo en utilizar este tipo de cosas, intento explicarme, tengo claro que la forma habitual de trabajar en .NET es que si pasas un tipo complejo a un método este siempre lo pasa por referencia, esto es cierto siempre y cuando ocupen el mismo espacio de memoria, que en el caso que nos ocupa NUNCA ocurre, porque para eso estamos a través de un proxy. Es preferible que tú método devuelva el mismo tipo y te lo pase cambiado y que los desarrolladores tengan muy clara la diferencia.&lt;/p&gt;

&lt;p&gt;Aunque bueno para gustos los colores así que cada uno tendrá su opinión.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Hasta la próxima…&lt;/p&gt;

&lt;p&gt;Mario Ropero…a medio gas…&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=156197" width="1" height="1"&gt;</description></item><item><title>CERRADO POR VACACIONES!!!!!</title><link>http://geeks.ms/blogs/mropero/archive/2009/07/31/cerrado-por-vacaciones.aspx</link><pubDate>Fri, 31 Jul 2009 11:20:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:153409</guid><dc:creator>Mario Ropero</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/mropero/rsscomments.aspx?PostID=153409</wfw:commentRss><comments>http://geeks.ms/blogs/mropero/archive/2009/07/31/cerrado-por-vacaciones.aspx#comments</comments><description>&lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p align="justify"&gt;El armario se cierra por vacaciones, qué ilusión que me hace poder decir esto. Voy a pasar las siguientes 6 (seis!!!!!!!) semanacas descansando, intentaré aprovechar para leer algo y culturizarme un poco, pero no creo que tenga mucho tiempo para escribir, así que dejaremos la actividad por un tiempo.&lt;/p&gt;  &lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;  &lt;p align="justify"&gt;Un saludo y disfrutad los que podáis.&lt;/p&gt;  &lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;  &lt;p align="justify"&gt;Mario Ropero.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=153409" width="1" height="1"&gt;</description></item><item><title>AYUDA : Validaciones vs Excepciones</title><link>http://geeks.ms/blogs/mropero/archive/2009/07/28/ayuda-validaciones-vs-excepciones.aspx</link><pubDate>Tue, 28 Jul 2009 08:23:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:153168</guid><dc:creator>Mario Ropero</dc:creator><slash:comments>16</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/mropero/rsscomments.aspx?PostID=153168</wfw:commentRss><comments>http://geeks.ms/blogs/mropero/archive/2009/07/28/ayuda-validaciones-vs-excepciones.aspx#comments</comments><description>&lt;p align="justify"&gt;Hola a todos, estamos en pleno periodo vacacional para algunos, otros no (nos queda poco, poco) y me ha surgido un problema, que espero que podáis ayudarme a resolver. Se refiere al tema de trabajar con validaciones o trabajar con excepciones y su rendimiento.&lt;/p&gt;  &lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;  &lt;p align="justify"&gt;A la hora de desarrollar un método cuando este recibe parámetros lo “ideal” es comprobar que los parámetros que nos llegan son válidos para utilizarlos en nuestra lógica posterior, así que según dicho esto lo que yo creo como ideal, es que la primera parte de un método sería validar la entrada de los parámetros y si está todo ok, seguir adelante.&lt;/p&gt;  &lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;  &lt;p align="justify"&gt;Bueno, en mi caso, la realidad es bastante diferente, en mi caso particular y “chapucero” (estoy intentando cambiar…), yo soy más de los de “try…catch” y listo y sí, debo admitir que algún catch vacío existe por mi código, aunque cada vez que lo veo digo “aghhhhhhh, mis ojos, mis ojos….”&lt;/p&gt;  &lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;  &lt;p align="justify"&gt;Esto es MALO, porque cuando te llegan varios parámetros o parámetros complejos y te da un error en el catch, no tienes la certeza de saber en qué punto te ha dado, lo normal es el típico error de “Object reference not set…” y listo, ahora tienes que averiguar en qué punto se te ha ido la pinza… &lt;/p&gt;  &lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;  &lt;p align="justify"&gt;En este caso está claro que lo mejor es validar la entrada y después hacer lo que tengas que hacer, pero mi problema está en el rendimiento, y pensaba que era mucho más eficiente validar que trabajar con la excepción, que costaría mucho más trabajar con una excepción que con validaciones, así que me generé un código sencillo para poder verlo.&lt;/p&gt;  &lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;    {&lt;br /&gt;      System.Diagnostics.Stopwatch sw = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; System.Diagnostics.Stopwatch();&lt;br /&gt;      sw.Start();&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; aux = 0; aux &amp;lt; 10; aux++)&lt;br /&gt;      {&lt;br /&gt;        DoSomething(&lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;);&lt;br /&gt;      }&lt;br /&gt;      Console.WriteLine(&lt;span style="color:#006080;"&gt;&amp;quot;Tiempo total Exception &amp;quot;&lt;/span&gt; + sw.Elapsed.TotalSeconds.ToString());&lt;br /&gt;      sw.Stop();&lt;br /&gt;      sw.Start();&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; aux = 0; aux &amp;lt; 10; aux++)&lt;br /&gt;      {&lt;br /&gt;        DoSomethingHasValue(&lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;);&lt;br /&gt;      }&lt;br /&gt;      Console.WriteLine(&lt;span style="color:#006080;"&gt;&amp;quot;Tiempo total HasValue &amp;quot;&lt;/span&gt; + sw.Elapsed.TotalSeconds.ToString());&lt;br /&gt;      Console.ReadLine();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; DoSomething(&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;? i)&lt;br /&gt;    {&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;try&lt;/span&gt;&lt;br /&gt;      {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; local = i.Value;&lt;br /&gt;      }&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;catch&lt;/span&gt; (Exception)&lt;br /&gt;      {&lt;br /&gt;        Console.WriteLine(&lt;span style="color:#006080;"&gt;&amp;quot;Valor de i nulo&amp;quot;&lt;/span&gt;);&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; DoSomethingHasValue(&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;? i)&lt;br /&gt;    {&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (i.HasValue)&lt;br /&gt;      {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; local = i.Value;&lt;br /&gt;      }&lt;br /&gt;    }&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p align="justify"&gt;Pues la salida de ese ejemplo es que las excepciones son un poco más rápidas que el “HasValue”, da igual que ponga 10, 100, 1000 o 10000, que compile en Debug o en Release, que ejecute dentro del Visual Studio o fuera.&lt;/p&gt;

&lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;

&lt;p align="justify"&gt;Lo único que vi, es que con las excepciones en el windbg (herramienta molona) genera un montón de ruido, por otra parte normal.&lt;/p&gt;

&lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;

&lt;p align="justify"&gt;Tengo varias cosas bastante claras, &lt;strong&gt;una es que se mucho mejor validar la entrada antes que dejar el control en un try…catch global&lt;/strong&gt;, aunque no se por rendimiento, el mantenimiento posterior será mucho más sencillo. Otra cosa es que seguro que el código que he puesto está mal pero no consigo encontrar dónde y la verdad, me sorprendió mucho que sea más rápido capturar una excepción que hacer una validación.&lt;/p&gt;

&lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;

&lt;p align="justify"&gt;Espero que podáis dedicar un tiempo y echarme una mano.&lt;/p&gt;

&lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;

&lt;p align="justify"&gt;Muchas gracias a todos.&lt;/p&gt;

&lt;p&gt;Mario Ropero.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;EDITO: Gracias a un &lt;a href="http://geeks.ms/user/Profile.aspx?UserID=2298"&gt;compi&lt;/a&gt; que ha visto el error del código que he puesto, he llegado a dos conclusiones, una soy un rato inútil por no haberlo visto antes y dos, realmente es mucho más eficiente validar antes que lanzar excepciones. Os dejo el código arreglado que lo comprueba:&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;[] args)&lt;br /&gt;    {&lt;br /&gt;      System.Diagnostics.Stopwatch sw = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; System.Diagnostics.Stopwatch();&lt;br /&gt;      sw.Start();&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; aux = 0; aux &amp;lt; 10; aux++)&lt;br /&gt;      {&lt;br /&gt;        DoSomething(&lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;);&lt;br /&gt;      }&lt;br /&gt;      Console.WriteLine(&lt;span style="color:#006080;"&gt;&amp;quot;Tiempo total Exception &amp;quot;&lt;/span&gt; + sw.Elapsed.TotalSeconds.ToString());&lt;br /&gt;      sw.Stop();&lt;br /&gt;      sw = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; System.Diagnostics.Stopwatch();&lt;br /&gt;      sw.Start();&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; aux = 0; aux &amp;lt; 10; aux++)&lt;br /&gt;      {&lt;br /&gt;        DoSomethingHasValue(&lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;);&lt;br /&gt;      }&lt;br /&gt;      Console.WriteLine(&lt;span style="color:#006080;"&gt;&amp;quot;Tiempo total HasValue &amp;quot;&lt;/span&gt; + sw.Elapsed.TotalSeconds.ToString());&lt;br /&gt;      Console.ReadLine();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; DoSomething(&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;? i)&lt;br /&gt;    {&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;try&lt;/span&gt;&lt;br /&gt;      {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; local = i.Value;&lt;br /&gt;      }&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;catch&lt;/span&gt; (Exception)&lt;br /&gt;      {&lt;br /&gt;        Console.WriteLine(&lt;span style="color:#006080;"&gt;&amp;quot;Valor de i nulo&amp;quot;&lt;/span&gt;);&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; DoSomethingHasValue(&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;? i)&lt;br /&gt;    {&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (i.HasValue)&lt;br /&gt;      {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; local = i.Value;&lt;br /&gt;      }      &lt;br /&gt;    }&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Gracias por vuestro tiempo. &lt;/p&gt;

&lt;p&gt;Un saludico.&lt;/p&gt;

&lt;p&gt;Mario.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=153168" width="1" height="1"&gt;</description></item><item><title>Ejecutar un servicio de Windows en 32-bit en un Windows de 64-bit</title><link>http://geeks.ms/blogs/mropero/archive/2009/07/17/ejecutar-un-servicio-de-windows-en-32-bit-en-un-windows-de-64-bit.aspx</link><pubDate>Fri, 17 Jul 2009 06:54:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:152543</guid><dc:creator>Mario Ropero</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/mropero/rsscomments.aspx?PostID=152543</wfw:commentRss><comments>http://geeks.ms/blogs/mropero/archive/2009/07/17/ejecutar-un-servicio-de-windows-en-32-bit-en-un-windows-de-64-bit.aspx#comments</comments><description>&lt;p align="justify"&gt;Hola a todos, llevo un tiempo apartado de los maravillosos mundos de &lt;em&gt;internés&lt;/em&gt;, porque estamos en fase de puesta en producción en mi proyecto actual, y ya sabéis como es eso. Muchos nervios por parte de la jefatura, se ven algún que otro látigo de siete colas, alguna que otra frase graciosa del tipo “¿Dormir? Para que necesitas dormir… a trabajar…” y cosas similares. Bueno, pues unos de los diversos cambios que se hizo fue en la plataforma y pasamos de un bonito Windows Server 2003 32 bit a su esplendido predecesor el Windows 2008 Server 64-bit. Y después de unas pruebas de concepto con la aplicación vimos que todo funcionaba incluso un poco mejor, pero…¿todo?, NO todo no funcionaba a la perfección. Teníamos un pequeño servicio de Windows que se encargaba de ejecutar unos procesillos asíncronamente que decidió dejar de funcionar.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p align="justify"&gt;La situación fue un poco caótica, un procesillo del que nadie se había acordado, paso a ser la prioridad número uno, vamos que se caía el mundo si eso no funcionaba. Y allí estaba yo, con un montón de jefes revoloteando a mi lado, mirando la pantalla de mi ordenador y sus smartphones viendo que el mundo se caía, y haciendo los típicos comentarios que imagino que todos hemos escuchado alguna vez “¿Ya está?”, “¿Seguro que eso es por &lt;em&gt;(poned aquí cualquier cosa que paso el día anterior que no tenga nada que ver con esto)&lt;/em&gt;?”, “Esto tiene que estar ya”. Y yo ahí aguantando el chaparrón y el servicio sólo me decía “No encuentro la xxx.dll”, y yo… “Joé, que la dll está aquí, ¿dónde quieres que te la deje corazón?”.&lt;/p&gt;  &lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;  &lt;p align="justify"&gt;Lo único que había cambiado era la plataforma, así que me dije, voy a ejecutarlo en 32-bit y a probar, y… más problemillas no tenía acceso al código para compilarlo para la plataforma x86, que sería la solución ideal, y busqué por internet y encontré una pequeña maravilla que se esconde en el &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=e6e1c3df-a74f-4207-8586-711ebe331cdc&amp;amp;displaylang=en"&gt;Windows 2008 SDK&lt;/a&gt; (esta herramienta es más antigua, pero para el 2008 se encuentra ahí), la herramienta &amp;#39;CorFlags.exe&amp;#39;.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p align="justify"&gt;Esta herramienta se encuentra en “C:\Program Files\Microsoft SDKs\Windows\v6.0\Bin\x64\CorFlags.exe “, y sirve para activar el modo 32BIT a un ejecutable, en mí caso el servicio.&lt;/p&gt;  &lt;p&gt;Para ejecutarla, es muy sencillo, si queremos poner el modo 32BIT:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;CoreFlags.exe Ejecutable.exe /32BIT+&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Si queremos quitar el modo 32BIT:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font face="Courier New"&gt;CoreFlags.exe Ejecutable.exe /32BIT-&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p align="justify"&gt;Y con eso todo empezó a funcionar. Y el pequeño proceso dejó de ser la prioridad uno, y todo el mundo respiró más tranquilo. Luego estuve investigando un poco más, y el problema no era el proceso en sí que puede ejecutarse en 32 o 64, era la dll que referenciaba (un proveedor de base de datos) que no estaba instalado en modo 64bit porque no existía.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Hasta la próxima.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=152543" width="1" height="1"&gt;</description></item><item><title>Una de TransactionScope por favor!!!!</title><link>http://geeks.ms/blogs/mropero/archive/2009/07/08/una-de-transactionscope-por-favor.aspx</link><pubDate>Wed, 08 Jul 2009 07:48:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:151978</guid><dc:creator>Mario Ropero</dc:creator><slash:comments>12</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/mropero/rsscomments.aspx?PostID=151978</wfw:commentRss><comments>http://geeks.ms/blogs/mropero/archive/2009/07/08/una-de-transactionscope-por-favor.aspx#comments</comments><description>&lt;p align="justify"&gt;Buenos días a todos, no tenía pensado en escribir nada de este maravilloso elemento, pero estamos haciendo una pequeña refactorización de código porque algún DBA nos dijo que en nuestra aplicación teníamos un poco de contención con las transacciones y yo pensé “Transacciones?? Si prácticamente no las usamos”, infeliz de mí, luego hice una búsqueda sencilla por el código y aquí estoy quitando código y escribiendo sobre esto.&lt;/p&gt;  &lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;  &lt;p align="justify"&gt;Lo que me he encontrado hasta la saciedad es esto&lt;/p&gt;  &lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (TransactionScope scope = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; TransactionScope(TransactionScopeOption.Required))&lt;br /&gt;{    &lt;br /&gt;    &lt;span style="color:#008000;"&gt;//Acción sobre base de datos&lt;/span&gt;&lt;br /&gt;    DoSomething.....&lt;br /&gt;    scope.Complete();&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p align="justify"&gt;Dónde el DoSomething es un Insert, un Update, un Delete o un Select (sí, sí… se ven cosas que dan mucho miedito), a ver… &lt;/p&gt;

&lt;p align="justify"&gt;¿PARA QUÉ NECESITAS UNA TRANSACCIÓN?, es que parece que si un insert está dentro de una transacción mola más o debe ser algo parecido, pero lo único que hace es NADA, o dar un poco por saco en todo caso.&lt;/p&gt;

&lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;

&lt;p align="justify"&gt;Otro caso gracioso es poner una transacción para una sentencia de selección, joe… esa es buenísima y la he visto demasiadas veces por desgracia, ahora imaginaos una select entre varias tablas de vuestra base de datos que sea pesada y que tenga un transactionscope con IsolationLevel a Serializable (uuuuuuuuuuuuhhh escalofríos me entran sólo de pensarlo).&lt;/p&gt;

&lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;

&lt;p align="justify"&gt;Otro tema son los transactionscopes encadenados, para hacer justamente eso, una acción, esto encima tiene delito porque pones a trabajar al DTC en una transacción distribuida, os pongo un ejemplito de código que me he encotrado, para que veáis:&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Metodo1()&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (TransactionScope scope = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; TransactionScope(TransactionScopeOption.Required))&lt;br /&gt;    {    &lt;span style="color:#008000;"&gt;//Acción sobre base de datos    &lt;/span&gt;&lt;br /&gt;        Metodo2();&lt;br /&gt;        scope.Complete()    &lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Metodo2()&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; (TransactionScope scope = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; TransactionScope(TransactionScopeOption.Required))&lt;br /&gt;    {    &lt;span style="color:#008000;"&gt;//Acción sobre base de datos    &lt;/span&gt;&lt;br /&gt;        DoSomething...&lt;br /&gt;        scope.Complete()    &lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;Conclusión&lt;/h4&gt;

&lt;p align="justify"&gt;Los TransactionScope están para lo que están, no para abusar de ellos porque nos pueden poner en situación bastante perjudiciales para el rendimiento de nuestra máquina, y nos pueden a llevar a bloqueos en base de datos sin quererlo. Así que se tienen que usar con cabeza y vuelvo a repetir, UNA ÚNICA OPERACIÓN EN BASE DE DATOS NO NECESITA UN TRANSACTIONSCOPE.&lt;/p&gt;

&lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;

&lt;p align="justify"&gt;Perdonad por el tono del post, es que estoy muy cabreado con esto, que estoy aquí pico y pala quitando transactionscopes que me salen por las orejillas, intentaré escribir algún post con algún ejemplo más tangible.&lt;/p&gt;

&lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;

&lt;p align="justify"&gt;Saludicos.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=151978" width="1" height="1"&gt;</description></item><item><title>[WCF] Pasar información entre las distintas “capas” del servidor</title><link>http://geeks.ms/blogs/mropero/archive/2009/07/07/wcf-pasar-informaci-243-n-entre-las-distintas-capas-del-servidor.aspx</link><pubDate>Tue, 07 Jul 2009 06:49:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:151914</guid><dc:creator>Mario Ropero</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/mropero/rsscomments.aspx?PostID=151914</wfw:commentRss><comments>http://geeks.ms/blogs/mropero/archive/2009/07/07/wcf-pasar-informaci-243-n-entre-las-distintas-capas-del-servidor.aspx#comments</comments><description>&lt;p align="justify"&gt;Hola a todos, siguiendo con los artículitos de WCF, os vengo a hablar de una solución que implementamos en un cliente para pasar información a través de su parte servidora sin tener que tocar la firma de los métodos, porque había unos cuantos. Esto se implementó a través del OperationContext que nos ofrece la activación del servicio WCF y la verdad es que funciona de vicio. Pero cómo me dijo un gran &lt;a href="https://mvp.support.microsoft.com/profile/Unai"&gt;crack&lt;/a&gt; sobre esto, hay que tener cuidado con el OperationContext porque no deja de ser una sesión de servidor, pero es finita y se sabe en qué momento se invalida y se crea. Os paso a contar el problema que teníamos…&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;El problema&lt;/h4&gt;  &lt;p align="justify"&gt;Bueno, el problema era más o menos sencillo, en la solución implementada existían entidades de datos muy, muy, muy pesadas y obtenerlas consumía mucho tiempo de base de datos e impactaba muchísimo en el rendimiento de la aplicación. Cómo la solución tenía una sesión de servidor ya implementada (cosa que ya quitamos), pues se metió una especie de cache que se creaba cuando se iniciaba la llamada al servicio y se destruía cuando se terminaba la ejecución del servicio. Pero estaba construida de aquella manera y cuando se sometió a pruebas de concurrencia… en fin, podría haber salido mejor.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;¿Qué necesitabamos?&lt;/h4&gt;  &lt;p align="justify"&gt;La necesidad era poder pasar las entidades que ya se habían obtenido de un método a otro, o de una capa a otra del servidor, para no tener que volver a obtenerlas una y otra vez. La respuesta clara y más sencilla… pasemos esa información en la llamada a los métodos. Después vimos que había que tocar muchos, muchos, muchos métodos y se descartó por tiempo y esfuerzo :-(&lt;/p&gt;  &lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;La solución que implementamos&lt;/h4&gt;  &lt;p&gt;Un compañero muy listo que tengo me dijo “oye, mira a ver si en el contexto de operación puedes pasar información personalizada”, así que me puse manos a la obra y encontré que se puede, vaya si se puede, a través de la interfaz IExtension. La verdad es que se pasa una hashtable (nos encantan las hashtables, tenemos kilo y medio de ellas) con la información que queremos, no es muy bonito, de hecho es feote, pero funciona (esta frase es uno de los peores males en esto de la programación…).&lt;/p&gt;  &lt;p&gt;Para hacer esto, creamos una clase que implemente la interfaz IExtension&amp;lt;IContextChannel&amp;gt;, porque queremos almacenar la información en el canal, y tenemos que implementar los métodos “Attach” y “Detach”. &lt;/p&gt;  &lt;p&gt;Algo parecido a esto&lt;/p&gt;  &lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; System.Collections;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; System.ServiceModel;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;namespace&lt;/span&gt; TestIExtension&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; ExtensionTest : IExtension&amp;lt;IContextChannel&amp;gt;&lt;br /&gt;    {&lt;br /&gt;        Hashtable mHash = &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; Hashtable Hash&lt;br /&gt;        {&lt;br /&gt;            get { &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; mHash; }&lt;br /&gt;            set { mHash = &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;; }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color:#cc6633;"&gt;#region&lt;/span&gt; IExtension&amp;lt;IContextChannel&amp;gt; Members&lt;br /&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Attach(IContextChannel owner)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (mHash == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;            {&lt;br /&gt;                mHash = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Hashtable();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Detach(IContextChannel owner)&lt;br /&gt;        {&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color:#cc6633;"&gt;#endregion&lt;/span&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Pensad que en vez de una hashtable en modo cajón desastre, se puede poner cualquier tipo de información.&lt;/p&gt;

&lt;p&gt;Para utilizar esta extensión en vuestro código, para recoger la información o para insertarla tendremos que utilizar el siguiento código:&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (OperationContext.Current != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt; &amp;amp;&amp;amp;&lt;br /&gt;    OperationContext.Current.Channel != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt; &amp;amp;&amp;amp;&lt;br /&gt;    OperationContext.Current.Channel.Extensions != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;    {&lt;br /&gt;        TestIExtension testExtension = OperationContext.Current.Channel.Extensions.Find&amp;lt;TestIExtension&amp;gt;();&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (testExtension != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; cacheExtension.Hash;       &lt;br /&gt;        }&lt;br /&gt;    }&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Como esta información está “viva” durante toda la activación del servicio, da exactamente igual desde que “capa” llamemos a este código porque siempre estará disponible.&lt;/p&gt;

&lt;p&gt;Otra cosa que encontramos que estaba bastante bien, es que aunque los servicios estén en modo Single, esta información se genera en cada llamada al servicio. Cosa totalmente lógica y normal, pero bueno en esto nunca se sabe :).&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;Conclusiones&lt;/h4&gt;

&lt;p&gt;WCF mola!!!! y el contexto de operación está genial y se le pueden hacer mil y una perrería, pero si me queda una cosa clara es que, la información que necesite un método se le debería pasar siempre por parámetros, vamos que un método debería disponer de toda la información que necesita de forma explícita y así no llevar a ninguna confusión, esto puede no ser cierto en todos los casos, pero en la medida de lo posible la simplicidad ayuda mucho (Keep it simple!!!!).&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Saludicos.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=151914" width="1" height="1"&gt;</description></item><item><title>[MSBuild] Crear y depurar una task personalizada</title><link>http://geeks.ms/blogs/mropero/archive/2009/06/30/msbuild-crear-y-depurar-una-task-personalizada.aspx</link><pubDate>Tue, 30 Jun 2009 11:02:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:151515</guid><dc:creator>Mario Ropero</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/mropero/rsscomments.aspx?PostID=151515</wfw:commentRss><comments>http://geeks.ms/blogs/mropero/archive/2009/06/30/msbuild-crear-y-depurar-una-task-personalizada.aspx#comments</comments><description>&lt;p align="justify"&gt;Hola a todos, vengo a hablar de una cosa que es tan sumamente sencilla que no har&amp;iacute;a falta escribir sobre ella, pero justamente por eso vamos a describirla. Vamos a crear una task personalizada para que nuestras builds automatizadas del VSTFS las ejecuten por nosotros.&lt;/p&gt;
&lt;p align="justify"&gt;Lo primero ser&amp;iacute;a deciros que las task sirven para casi cualquier cosa que se nos ocurra en nuestras build, en mi caso particular la &amp;uacute;ltima vez que hice una era para sustituir un fichero .bat que organizaba unos ficheros de salida y claro con el task realmente hacia lo mismo, pero era m&amp;aacute;s vers&amp;aacute;til y molaba m&amp;aacute;s.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;Crear una task&lt;/h4&gt;
&lt;p align="justify"&gt;Esto es lo m&amp;aacute;s sencillo, creamos un proyecto de tipo class library (por poner un ejemplo), y a&amp;ntilde;adimos las siguientes referencias:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div align="justify"&gt;Microsoft.Build.Framework (en mi caso la versi&amp;oacute;n 3.5)&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div align="justify"&gt;Microsoft.Build.Utilities.v3.5&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Generamos una clase y la hacemos heredar de &amp;ldquo;Task&amp;rdquo; (que se encuentra en Microsoft.Build.Utilities). Realizamos una implementaci&amp;oacute;n del m&amp;eacute;todo &amp;ldquo;Execute&amp;rdquo; de la base y listo, ya tenemos nuestra task personalizada.&lt;/p&gt;
&lt;p&gt;Quedar&amp;iacute;a algo similar a esto,&lt;/p&gt;
&lt;div id="codeSnippetWrapper" style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;cursor:text;border:silver 1px solid;padding:4px;"&gt;
&lt;pre id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; Microsoft.Build.Utilities;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;namespace&lt;/span&gt; TestTask&lt;br /&gt;{&lt;br /&gt;  &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; HolaNombreTask : Task&lt;br /&gt;  {&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; Execute()&lt;br /&gt;    {&lt;br /&gt;      Log.LogMessage(&lt;span style="color:#006080;"&gt;&amp;quot;Hola Mario!!!&amp;quot;&lt;/span&gt;);&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Notad que no he usado el hola mundo, he usado hola Mario porque soy un poco egoc&amp;eacute;ntrico (aunque me contento con poquillo)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;A&amp;ntilde;adir par&amp;aacute;metros obligatorios&lt;/h4&gt;
&lt;p&gt;Ya tendr&amp;iacute;amos el task, ahora lo ideal es pasarle alg&amp;uacute;n que otro parametrillo, la forma es igual de f&amp;aacute;cil, s&amp;oacute;lo tenemos que a&amp;ntilde;adir una propiedad p&amp;uacute;blica y ya lo tendr&amp;iacute;amos.&lt;/p&gt;
&lt;p&gt;Vamos a a&amp;ntilde;adir un par&amp;aacute;metro obligatorio para que se indique un nombre.&lt;/p&gt;
&lt;p&gt;Al final el c&amp;oacute;digo quedar&amp;iacute;a c&amp;oacute;mo sigue,&lt;/p&gt;
&lt;div id="codeSnippetWrapper" style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;cursor:text;border:silver 1px solid;padding:4px;"&gt;
&lt;pre id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; Microsoft.Build.Utilities;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; Microsoft.Build.Framework;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;namespace&lt;/span&gt; TestTask&lt;br /&gt;{&lt;br /&gt;  &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; HolaNombreTask : Task&lt;br /&gt;  {&lt;br /&gt;    [Required]&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Nombre { get; set; }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; Execute()&lt;br /&gt;    {&lt;br /&gt;      Log.LogMessage(&lt;span style="color:#006080;"&gt;&amp;quot;Hola &amp;quot;&lt;/span&gt; + Nombre);&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p align="justify"&gt;Vamos a ver c&amp;oacute;mo se depura esto a trav&amp;eacute;s del visual studio, porque lo que interesa es que se ejecute a trav&amp;eacute;s de msbuild, no probar el m&amp;eacute;todo que vemos que es muy sencillo y no deber&amp;iacute;a fallar&amp;hellip;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;Depurar task con msbuild&lt;/h4&gt;
&lt;p align="justify"&gt;Necesitaremos generar un xml que pueda leer el msbuild y que haga ejecutar nuestra task. As&amp;iacute; que creamos un nuevo fichero xml (testtask.xmldebug) con el siguiente contenido&lt;/p&gt;
&lt;div id="codeSnippetWrapper" style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;width:97.5%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;cursor:text;border:silver 1px solid;padding:4px;"&gt;
&lt;pre id="codeSnippet" style="text-align:left;line-height:12pt;background-color:#f4f4f4;margin:0em;width:100%;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;color:black;font-size:8pt;overflow:visible;border-style:none;padding:0px;"&gt;&amp;lt;?xml version=&lt;span style="color:#006080;"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt; encoding=&lt;span style="color:#006080;"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt; ?&amp;gt;&lt;br /&gt;&amp;lt;Project DefualtTargets=&lt;span style="color:#006080;"&gt;&amp;quot;Debug&amp;quot;&lt;/span&gt; xmlns=&lt;span style="color:#006080;"&gt;&amp;quot;http://schemas.microsoft.com/developer/msbuild/2003&amp;quot;&lt;/span&gt;&amp;gt;&lt;br /&gt;  &amp;lt;UsingTask TaskName=&lt;span style="color:#006080;"&gt;&amp;quot;HolaNombreTask&amp;quot;&lt;/span&gt; AssemblyFile = &lt;span style="color:#006080;"&gt;&amp;quot;C:\TestTask\bin\Debug\TestTask.dll&amp;quot;&lt;/span&gt; /&amp;gt;&lt;br /&gt;  &amp;lt;Target Name=&lt;span style="color:#006080;"&gt;&amp;quot;Debug&amp;quot;&lt;/span&gt;&amp;gt;&lt;br /&gt;    &amp;lt;HolaNombreTask&lt;br /&gt;      Nombre=&lt;span style="color:#006080;"&gt;&amp;quot;Mario!!!&amp;quot;&lt;/span&gt;&lt;br /&gt;      /&amp;gt;&lt;br /&gt;  &amp;lt;/Target&amp;gt;&lt;br /&gt;&amp;lt;/Project&amp;gt;&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p align="justify"&gt;A tener en cuenta, el tag &amp;ldquo;UsingTask&amp;rdquo; que evidentemente sirve para utilizar una task que est&amp;eacute; en el ensamblado que le pongamos, en nuetro caso el que acabamos de generar, y poquito m&amp;aacute;s, creo que est&amp;aacute; bastante claro el documentito xml.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p align="justify"&gt;Ahora tenemos que ir a las propiedades de nuestro proyecto, a la &amp;ldquo;pesta&amp;ntilde;a&amp;rdquo; Debug y,&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div align="justify"&gt;Marcamos la opci&amp;oacute;n de &amp;ldquo;Start external program:&amp;rdquo; y buscamos el MSBuild.exe que normalmente se encuentra en %windir%\Microsoft.NET\v3.5\MSBuild.exe &lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div align="justify"&gt;Y en &amp;ldquo;Command line argumetns&amp;rdquo; ponemos la direcci&amp;oacute;n d&amp;oacute;nde se encuentra el fichero xml que hemos generado, en el caso del ejemplo (&amp;ldquo;C:\TestTask\testtask.xmldebug&amp;rdquo;)&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div align="justify"&gt;Ponemos alg&amp;uacute;n puntico de parada si queremos&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div align="justify"&gt;Pulsamos F5 y ya est&amp;aacute;&amp;hellip;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Ya tenemos nuestra task funcionando y depur&amp;aacute;ndola a nuestro gusto. &lt;/p&gt;
&lt;p&gt;Como pod&amp;eacute;is observar es super sencillo generar nuevas task.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Un saludico y hasta la pr&amp;oacute;xima.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=151515" width="1" height="1"&gt;</description></item><item><title>[WCF] InstanceContextMode.Single y variables globales</title><link>http://geeks.ms/blogs/mropero/archive/2009/06/25/wcf-instancecontextmode-single-y-variables-globales.aspx</link><pubDate>Thu, 25 Jun 2009 09:10:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:151219</guid><dc:creator>Mario Ropero</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/mropero/rsscomments.aspx?PostID=151219</wfw:commentRss><comments>http://geeks.ms/blogs/mropero/archive/2009/06/25/wcf-instancecontextmode-single-y-variables-globales.aspx#comments</comments><description>&lt;p align="justify"&gt;Los servicios WCF (esos grandes amiguitos), tiene varios modos de instanciación (PerCall, PerSession y Single), la documentación oficial la podéis encontrar &lt;a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.instancecontextmode.aspx"&gt;aquí&lt;/a&gt;, pero quería hablaros del comportamiento del single.&lt;/p&gt;  &lt;p align="justify"&gt;En mi proyecto actual se decidió cambiar la forma de instanciación de los servicios a Single para ganar rendimiento, y en un principio viendo el coste del cambio, “unas dos líneas de código”(jajajajajaja), se decidió hacerlo. Yo en un principio era un poco escéptico porque conocía como estaba construida la “casa” y en fin… tenía mis dudillas, y la verdad se nos complicó un poco el cambio, os cuento…&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p align="justify"&gt;Un poquillo de culturilla, cuándo se instancia un servicio en modo Single, se crea una única instancia si no existe y si ya existe no se crea nada (lo que viene siendo un Singleton), esto es genial, lo que pasa es que todas las llamadas que haga ese servicio a nuevas clases realmente van a tener una única referencia y no se van a estar creando nuevas clases una y otra vez, vamos que el “new class()” realmente no tiene por qué crear una nueva instancia, si no reutilizar una ya creada. Este comportamiento, totalmente lógico, puede dar algún problema porque no es del todo explícito.&lt;/p&gt;  &lt;p align="justify"&gt;   &lt;br /&gt;Yo hasta aquí, no le veo más que ventajas, nuestro proyecto actual tenía un montón de problemas de rendimiento porque se generaban muchas llamadas a servicios (bueno esa era una de las muchísimas razones), así que nos pusimos manos a la obra y… zas en toda la boca. De buenas a primeras los servicios no conseguían levantarse, y los que lo conseguían en unas mínimas pruebas de carga empezaron a dar problemas de concurrencia y los que no los daban no funcionaban como tenían que funcionar.&lt;/p&gt;  &lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;  &lt;p align="justify"&gt;Después de los primeros momentos de pánico y miradas asesinas hacia los pobrecillos que hicimos el cambio, nos pusimos a mirar detenidamente y vimos que en nuestras clases de lógica de negocio y acceso a datos se usaban muchas, muchísimas variables globales (no, no, no…chicos malos). El “problema” es que cuando se está trabajando en un servicio en modo Single, cualquiera de sus clases que estén dentro del contexto de la llamada del servicio estarán apuntando a una única referencia y también “están” en modo single, así que a todos los efectos&lt;/p&gt;  &lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; UnaDAL()&lt;br /&gt;{&lt;br /&gt;    List&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt; listaEnteros = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; List&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt;();&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;se convierte en algo similar a esto&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; UnaDAL()&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; List&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt; listaEnteros = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; List&amp;lt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt;&amp;gt;()&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Pues claro si luego la utilizas sin locks y sin pensar en la concurrencia, esto no funciona.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;Conclusiones&lt;/h4&gt;

&lt;p align="justify"&gt;Todos a una… “Las variables globales son malas”, aunque las generalizaciones son malas, en general no se deberían utilizar salvo en casos realmente necesarios y controlados. Y por otra parte, creo que utilizar los servicios en modo single se tiene que hacer cuándo tú aplicación lo soporta o está medianamente bien diseñada. En nuestro caso actual, estamos trabajando en ello y parece que vemos la luz del túnel y la verdad es que ahora mismo nuestras clases tienen mucha mejor forma y salud… Aunque debo deciros que los primeros momentos de pánico fueron muy graciosos…&lt;/p&gt;

&lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Un saludico y hasta la próxima.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=151219" width="1" height="1"&gt;</description></item><item><title>[WCF] Usar ClientMessageInspector para añadir información a las soapHeaders</title><link>http://geeks.ms/blogs/mropero/archive/2009/06/14/wcf-a-241-adir-informaci-243-n-en-las-soapheaders.aspx</link><pubDate>Sun, 14 Jun 2009 08:56:35 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:150471</guid><dc:creator>Mario Ropero</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/mropero/rsscomments.aspx?PostID=150471</wfw:commentRss><comments>http://geeks.ms/blogs/mropero/archive/2009/06/14/wcf-a-241-adir-informaci-243-n-en-las-soapheaders.aspx#comments</comments><description>&lt;p align="justify"&gt;Hay ocasiones que queremos pasar información del cliente al servidor, o vicerversa y no queremos cambiar la fachada de nuestros métodos, o bien porque implicaría mucho cambio, o bien porque la información que queremos transportar es una información de “estado” que no tiene sentido que esté en la fachada de nuestros métodos. &lt;/p&gt;  &lt;p align="justify"&gt;Pues esto lo vamos a poder hacer a través de los behavior de los endpoint y de los MessageInspector, que existen de dos clases, los de cliente (IClientMessageInspector) y los de servidor (IDispatchMessageInspector). Y me vais a perdonar porque no tienen que estar necesariamente en cliente o en servidor, pero este es un punto de partida.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p align="justify"&gt;1.- Definimos una clase que va a ser nuestro MessageInspector y hacemos que implemente la interfaz IClientMessageInspector&lt;/p&gt;  &lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;namespace&lt;/span&gt; ClientInspector&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; ClientMessageInspector : System.ServiceModel.Dispatcher.IClientMessageInspector&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;         &lt;span style="color:#cc6633;"&gt;#region&lt;/span&gt; IClientMessageInspector Members&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; AfterReceiveReply(&lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; System.ServiceModel.Channels.Message reply, &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; correlationState)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;         {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;         }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; BeforeSendRequest(&lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt;         {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum14"&gt;  14:&lt;/span&gt;             &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; Guid.NewGuid();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum15"&gt;  15:&lt;/span&gt;         }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum16"&gt;  16:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum17"&gt;  17:&lt;/span&gt;         &lt;span style="color:#cc6633;"&gt;#endregion&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum18"&gt;  18:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum19"&gt;  19:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;2.- En el método BeforeSendRequest, es dónde tenemos que añadir información en las soapHeaders, en el ejemplo vamos a insertar un guid, pero se podría insertar cualquier cosa&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; BeforeSendRequest(&lt;span style="color:#0000ff;"&gt;ref&lt;/span&gt; System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     MessageHeader&amp;lt;Guid&amp;gt; mhg = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; MessageHeader&amp;lt;Guid&amp;gt;(Guid.NewGuid());&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;     MessageHeader untyped = mhg.GetUntypedHeader(&lt;span style="color:#006080;"&gt;&amp;quot;GuidToken&amp;quot;&lt;/span&gt;, &lt;span style="color:#006080;"&gt;&amp;quot;gtk&amp;quot;&lt;/span&gt;);            &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;     request.Headers.Add(untyped);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; Guid.NewGuid();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p align="justify"&gt;Ahora mismo tenemos definido el MessageInspector de cliente y lo que hará cuando se llame, lo siguiente es aplicarlo a través de un EndPointBehavior.&lt;/p&gt;

&lt;p align="justify"&gt;3.- Definimos un custom Behavior para que aplique nuestro message inspector, así que creamos una clase que implemente la interfaz IEndpointBehavior&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;namespace&lt;/span&gt; ClientInspector&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {    &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; InspectorBehavior : IEndpointBehavior&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;         &lt;span style="color:#cc6633;"&gt;#region&lt;/span&gt; IEndpointBehavior Members&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt;         {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt;         }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;         {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt;         }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt;             &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum14"&gt;  14:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum15"&gt;  15:&lt;/span&gt;         {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum16"&gt;  16:&lt;/span&gt;         }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum17"&gt;  17:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum18"&gt;  18:&lt;/span&gt;         &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Validate(ServiceEndpoint endpoint)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum19"&gt;  19:&lt;/span&gt;         {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum20"&gt;  20:&lt;/span&gt;         }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum21"&gt;  21:&lt;/span&gt;         &lt;span style="color:#cc6633;"&gt;#endregion&lt;/span&gt;        &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum22"&gt;  22:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum23"&gt;  23:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p align="justify"&gt;4.- En el método ApplyClientBehavior, es dónde añadimos el MessageInspector que hemos creado en los pasos anteriores&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt;     ClientMessageInspector inspector = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ClientMessageInspector();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt;     clientRuntime.MessageInspectors.Add(inspector);&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p align="justify"&gt;Con esto ya tendríamos el behavior listo y para aplicarlo por código, en una service reference ya creada en nuestro proyecto, tendríamos que añadirlo a la lista de behaviors del EndPoint, un ejemplo de esto sería.&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;height:40px;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; client.Endpoint.Behaviors.Add(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ClientInspector.InspectorBehavior());&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p align="justify"&gt;Con estas tres líneas se puede leer la cabecera que hemos insertado. Esto se haría en la parte “servidora”&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#008000;"&gt;//Leer información de las cabeceras&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span style="color:#008000;"&gt;//Recoger la cabecera que ha insertado el behavior&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (OperationContext.Current.IncomingMessageHeaders.FindHeader(&lt;span style="color:#006080;"&gt;&amp;quot;GuidToken&amp;quot;&lt;/span&gt;, &lt;span style="color:#006080;"&gt;&amp;quot;gtk&amp;quot;&lt;/span&gt;) &amp;gt;= 0)&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt;     Console.WriteLine(OperationContext.Current.IncomingMessageHeaders.GetHeader&amp;lt;Guid&amp;gt;(&lt;span style="color:#006080;"&gt;&amp;quot;GuidToken&amp;quot;&lt;/span&gt;, &lt;span style="color:#006080;"&gt;&amp;quot;gtk&amp;quot;&lt;/span&gt;).ToString());&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p align="justify"&gt;Os dejo el código fuente del ejemplito &lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/mropero.Samples/TestClientInspectorWithoutExtension.zip"&gt;aquí&lt;/a&gt;.&lt;/p&gt;

&lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;

&lt;p align="justify"&gt;Ya estaría, aunque faltaría un punto bastante importante, nosotros queremos hacer todo esto a través de un fichero de configuración porque no apetece nada tener que ir por el código añadiendo el behavior a cada service reference que tengamos… ¿verdad?… &lt;/p&gt;

&lt;p align="justify"&gt;&amp;#160;&lt;/p&gt;

&lt;h4 align="justify"&gt;¿Cómo añadir un behaviorExtension al fichero de configuración?&lt;/h4&gt;

&lt;p align="justify"&gt;Bueno pues ese problema también está resuelto heredando de BehaviorExtensionElement.&lt;/p&gt;

&lt;p align="justify"&gt;1.- Añadimos la clase al ejemplito anterior&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; System;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; System.Linq;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum4"&gt;   4:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; System.Text;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum5"&gt;   5:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; System.ServiceModel.Configuration;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum6"&gt;   6:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum7"&gt;   7:&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;namespace&lt;/span&gt; ClientInspector&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum8"&gt;   8:&lt;/span&gt; {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum9"&gt;   9:&lt;/span&gt;   &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; InspectorBehaviorExtension : BehaviorExtensionElement&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum10"&gt;  10:&lt;/span&gt;   {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum11"&gt;  11:&lt;/span&gt;     &lt;span style="color:#008000;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum12"&gt;  12:&lt;/span&gt;     &lt;span style="color:#008000;"&gt;/// BehaviorType&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum13"&gt;  13:&lt;/span&gt;     &lt;span style="color:#008000;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum14"&gt;  14:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; Type BehaviorType&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum15"&gt;  15:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum16"&gt;  16:&lt;/span&gt;       get { &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(InspectorBehavior); }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum17"&gt;  17:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum18"&gt;  18:&lt;/span&gt;&amp;#160; &lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum19"&gt;  19:&lt;/span&gt;     &lt;span style="color:#008000;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum20"&gt;  20:&lt;/span&gt;     &lt;span style="color:#008000;"&gt;/// CreateBehavior&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum21"&gt;  21:&lt;/span&gt;     &lt;span style="color:#008000;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum22"&gt;  22:&lt;/span&gt;     &lt;span style="color:#008000;"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum23"&gt;  23:&lt;/span&gt;     &lt;span style="color:#0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; CreateBehavior()&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum24"&gt;  24:&lt;/span&gt;     {&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum25"&gt;  25:&lt;/span&gt;       &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; InspectorBehavior();&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum26"&gt;  26:&lt;/span&gt;     }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:white;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum27"&gt;  27:&lt;/span&gt;   }&lt;/pre&gt;


    &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;"&gt;&lt;span style="color:#606060;" id="lnum28"&gt;  28:&lt;/span&gt; }&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Con esta clase ya compilada y funcionando, ya podríamos configurar el behavior en el fichero de configuración, aplicarlo al endpoint y quitar la llamada del código que hemos puesto.&lt;/p&gt;

&lt;p&gt;Os muestro el fichero de configuración y luego os comento las entradas “especiales” (que no tienen nada de especiales) para que esto funcione. He quitado la parte del binding… porque en este caso no nos preocupa…&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&amp;lt;?xml version=&lt;span style="color:#006080;"&gt;&amp;quot;1.0&amp;quot;&lt;/span&gt; encoding=&lt;span style="color:#006080;"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt; ?&amp;gt;&lt;br /&gt;&amp;lt;configuration&amp;gt;&lt;br /&gt;    &amp;lt;system.serviceModel&amp;gt;&lt;br /&gt;        &amp;lt;behaviors&amp;gt;&lt;br /&gt;            &amp;lt;endpointBehaviors&amp;gt;   &lt;br /&gt;                &amp;lt;behavior name=&lt;span style="color:#006080;"&gt;&amp;quot;BehaviorConInspector&amp;quot;&lt;/span&gt;&amp;gt;&lt;br /&gt;                  &amp;lt;InspectorExtension /&amp;gt;&lt;br /&gt;                &amp;lt;/behavior&amp;gt;&lt;br /&gt;            &amp;lt;/endpointBehaviors&amp;gt;&lt;br /&gt;        &amp;lt;/behaviors&amp;gt;&lt;br /&gt;        &amp;lt;extensions&amp;gt;&lt;br /&gt;            &amp;lt;behaviorExtensions&amp;gt;&lt;br /&gt;                &amp;lt;add name=&lt;span style="color:#006080;"&gt;&amp;quot;InspectorExtension&amp;quot;&lt;/span&gt; type=&lt;span style="color:#006080;"&gt;&amp;quot;ClientInspector.InspectorBehaviorExtension, ClientInspector, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null&amp;quot;&lt;/span&gt; /&amp;gt;&lt;br /&gt;            &amp;lt;/behaviorExtensions&amp;gt;&lt;br /&gt;        &amp;lt;/extensions&amp;gt;&lt;br /&gt;        &amp;lt;bindings&amp;gt;&lt;br /&gt;            &amp;lt;ws2007HttpBinding&amp;gt;&lt;br /&gt;                &amp;lt;binding name=&lt;span style="color:#006080;"&gt;&amp;quot;WS2007HttpBinding_ISampleService&amp;quot;&lt;/span&gt; ...&amp;gt;&lt;br /&gt;                &amp;lt;/binding&amp;gt;&lt;br /&gt;            &amp;lt;/ws2007HttpBinding&amp;gt;&lt;br /&gt;        &amp;lt;/bindings&amp;gt;&lt;br /&gt;        &amp;lt;client&amp;gt;&lt;br /&gt;            &amp;lt;endpoint address=&lt;span style="color:#006080;"&gt;&amp;quot;http://localhost:8090/SampleService&amp;quot;&lt;/span&gt; behaviorConfiguration=&lt;span style="color:#006080;"&gt;&amp;quot;BehaviorConInspector&amp;quot;&lt;/span&gt;&lt;br /&gt;                binding=&lt;span style="color:#006080;"&gt;&amp;quot;ws2007HttpBinding&amp;quot;&lt;/span&gt; bindingConfiguration=&lt;span style="color:#006080;"&gt;&amp;quot;WS2007HttpBinding_ISampleService&amp;quot;&lt;/span&gt;&lt;br /&gt;                contract=&lt;span style="color:#006080;"&gt;&amp;quot;ServiceReference1.ISampleService&amp;quot;&lt;/span&gt; name=&lt;span style="color:#006080;"&gt;&amp;quot;WS2007HttpBinding_ISampleService&amp;quot;&lt;/span&gt; /&amp;gt;&lt;br /&gt;        &amp;lt;/client&amp;gt;&lt;br /&gt;    &amp;lt;/system.serviceModel&amp;gt;&lt;br /&gt;&amp;lt;/configuration&amp;gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Aquí las cosas que hemos cambiado son, extensions, behaviors y el endpoint de client.&lt;/p&gt;

&lt;h4&gt;BehaviorExtension&lt;/h4&gt;

&lt;p&gt;Lo primero de todo es añadir una behaviorextension que es lo que hemos conseguido haciendo la clase que heredaba de BehaviorExtensionElement (su propio nombre lo indica), eso se añade con &lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&amp;lt;extensions&amp;gt;&lt;br /&gt;    &amp;lt;behaviorExtensions&amp;gt;&lt;br /&gt;        &amp;lt;add name=&lt;span style="color:#006080;"&gt;&amp;quot;InspectorExtension&amp;quot;&lt;/span&gt; type=&lt;span style="color:#006080;"&gt;&amp;quot;ClientInspector.InspectorBehaviorExtension, ClientInspector, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null&amp;quot;&lt;/span&gt; /&amp;gt;&lt;br /&gt;    &amp;lt;/behaviorExtensions&amp;gt;&lt;br /&gt;&amp;lt;/extensions&amp;gt;&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;Behavior&lt;/h4&gt;

&lt;p&gt;Hay que añadir un nuevo behavior que tenga nuestra extension para que se ejecute el inspector, como queremos hacer&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&amp;lt;behaviors&amp;gt;&lt;br /&gt;    &amp;lt;endpointBehaviors&amp;gt;   &lt;br /&gt;        &amp;lt;behavior name=&lt;span style="color:#006080;"&gt;&amp;quot;BehaviorConInspector&amp;quot;&lt;/span&gt;&amp;gt;&lt;br /&gt;            &amp;lt;InspectorExtension /&amp;gt;&lt;br /&gt;        &amp;lt;/behavior&amp;gt;&lt;br /&gt;    &amp;lt;/endpointBehaviors&amp;gt;&lt;br /&gt;&amp;lt;/behaviors&amp;gt;&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Aquí además se puede añadir cualquier tipo de configuración asociada a los behavior como se hace normalmente.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;Client endpoint&lt;/h4&gt;

&lt;p&gt;Lo último, y bastante importante, es decirle a nuestro endpoint de cliente que utilice ese behavior, porque si no, esto no habría valido para nada :)&lt;/p&gt;

&lt;p&gt;Para esto, sólo hay que añadir en la configuración de cliente el atributo behaviorConfiguration = “BehaviorConInspector”. &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Y listo, ya podríamos probar quitando la línea que añade el inspector explícitamente en el código y funcionaría exactamente igual&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;Este post se acabó….&lt;/h4&gt;

&lt;p&gt;Os dejo el código fuente con esto cambiado &lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/mropero.Samples/TestClientInspector.zip"&gt;aquí&lt;/a&gt;, por si queréis comparar.&lt;/p&gt;

&lt;p&gt;Cómo habréis podido observar, me he roto los cuernos pensando los nombrecicos así que no lo toméis muy a mal… :). Esto de meter información en las cabeceras de los mensajes mola!!!. En el proyecto actual, lo usamos para quitar una sesión de servidor (sí…es malvada y no permite escalar las aplicaciones… por eso la queríamos quitar), y la verdad es que va muy bien.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Saludicos y hasta la próxima.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=150471" width="1" height="1"&gt;</description></item><item><title>Producir, producir y producir!!!!</title><link>http://geeks.ms/blogs/mropero/archive/2009/06/11/producir-producir-y-producir.aspx</link><pubDate>Thu, 11 Jun 2009 17:51:34 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:150361</guid><dc:creator>Mario Ropero</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/mropero/rsscomments.aspx?PostID=150361</wfw:commentRss><comments>http://geeks.ms/blogs/mropero/archive/2009/06/11/producir-producir-y-producir.aspx#comments</comments><description>&lt;p align="justify"&gt;Actualmente, estoy trabajando desplazado en un cliente ayudándoles (o al menos intentándolo) al sacar adelante su aplicación interna de gestión, el trabajo es duro y el tiempo es corto… vamos que estamos en la mejor de las situaciones que imagino que muchos de vosotros, por desgracia, conoceréis.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p align="justify"&gt;De ahí, el tema del “post”, en una situación como la actual lo que se pide a los desarrolladores es que produzcan, produzcan y que produzcan… y que además lo produzcan bien (bueno esto último es un decir). Para ello nos dan una herramienta maravillosa que se llama Microsoft Visual Studio 2008 y una “bonita” solución de… 200 proyectos (y sí, habéis leído bien 200 proyectos!!!).&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p align="justify"&gt;Nosotros le hemos cogido cariño a la solución y es nuestra “bicha”, y la susodicha tarda aproximadamente 20 minutos en compilar… ¿Os podéis imaginar el tiempo que se pierde para corregir una incidencia?……… MUCHO, de hecho muchísimo… además pierdes la concentración y al final pierdes las ganas de arreglar las incidencias.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;¿Cómo se ha llegado a esto?&lt;/h4&gt;  &lt;p align="justify"&gt; La verdad, no tengo ni idea, yo solo pasaba por allí. Pero hay una mezcolanza de arquitecturas y de formas de dividir una solución que al final hay muchísimos proyectos, todos relacionados entre sí y hasta alguna referencia circular… (sí, ya se que Visual Studio no te deja… pero es que también usamos reflection a cascoporro… así que “si quieres, puedes”).&lt;/p&gt;  &lt;p align="justify"&gt;Yo aquí sólo diría que una vez que nos ponemos a intentar organizar una solución y todos sus proyectos, podemos hacer divisiones de ensamblados funcionalmente, o técnicamente… que podemos dividirlos por “LogicaNegocio”, “CapaDatos”, “Modelo”,…. o por “Compras”, “Proveedores”, “Clientes”… pero por favor no los mezcléis porque si no… terminaréis con una “bicha” y os aseguro que no es para nada bueno…&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;¿Por qué tarda tanto en compilar?&lt;/h4&gt;  &lt;p&gt; La respuesta es sencilla y tiene dos o tres puntos:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;1. Son muchos proyectos&lt;/p&gt;    &lt;p&gt;2. Los proyectos tienen muchas referencias del tipo “Proyecto” a los distintos proyectos (redundante ¿eh? :-))&lt;/p&gt;    &lt;p&gt;3. Existe algún proyecto excesivamente grande o con un número demasiado grande de referencias&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Seguro que existen muchas más razones pero estas son las que se me ocurren a mí…&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;¿Se podría reducir el tiempo de compilación?&lt;/h4&gt;  &lt;p align="justify"&gt;Sí, y la primera respuesta que se me viene a la cabeza es… “REUNIFICANDO PROYECTOS”, aunque también se podrían poner las referencias a ensamblados previamente compilados y no tardaría mucho, o intentar redefinir los proyectos con un elevado número de referencias.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;¿Tiene algún tipo de fundamento reorganizar el código en menos proyectos?&lt;/h4&gt;  &lt;p&gt;Una vez visto el problema que tenemos en la parte de desarrollo y no olvidando nunca que nuestra función fundamente es producir, producir y producir un poquito más, estuve buceando un poco por Internet y preguntando a algún que otro crá de esto de la informática y al final creo que el sentido común es lo que triunfa. &lt;/p&gt;  &lt;p&gt;Así que es mejor tener un proyecto un poco más grande que tener cinco proyectos pequeñitos, y cuándo este número crece mucho, se hace bastante importante, porque:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;1. Se reduce el número de proyectos (esto es obvio)&lt;/p&gt;    &lt;p&gt;2. Se reduce el número de referencias&lt;/p&gt;    &lt;p&gt;3. Se puede evitar el efecto “rebase” (esto no es muy importante cuando se tienen pocos proyectos pero bueno… algo es algo)&lt;/p&gt;    &lt;p&gt;4. El JITTER utiliza menos tiempo&lt;/p&gt;    &lt;p&gt;5 …&lt;/p&gt;    &lt;p&gt;&amp;#160;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Esto viene todo de un bonito sitio que se llama “Microsoft Pattern &amp;amp; Practices” y bueno parece que estos chicos saben un poquillo de esto, os dejo los links que son bastante aclaradores.&lt;/p&gt;  &lt;p&gt;&lt;a href="https://mail.avanade.com/redir.aspx?C=3b9e085ffb984163a60c36d19a413341&amp;amp;URL=http%3a%2f%2fmsdn.microsoft.com%2fen-us%2flibrary%2fms998547.aspx%23scalenetchapt05_topic33"&gt;http://msdn.microsoft.com/en-us/library/ms998547.aspx#scalenetchapt05_topic33&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms979052.aspx"&gt;http://msdn.microsoft.com/en-us/library/ms979052.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;h4&gt;¿Conclusión?&lt;/h4&gt;  &lt;p&gt;Bueno la conclusión es sencilla… da igual de qué forma se optimice el tiempo de compilación pero es un tiempo que debería ser nulo o muy pequeño si no queremos que el ritmo de producción se vea alterado por otras causas ajenas a nuestras meteduras de pata. Yo en este cliente en particular intento reducir el número de proyectos.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Perdonad por el rollazo, este es mi primer post de lo que espero sea una larga lista de ellos, y no tengo intención de que sean de este tipo si no algo más orientado a ayudas con el código para hacer ciertas cosas, pero es que este tema me tiene comidita la moral y creo que es muy importante que nosotros los desarrolladores no nos muramos cada vez que intentemos compilar una solución.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=150361" width="1" height="1"&gt;</description></item></channel></rss>
