<?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>Burbujas en .NET : patrones</title><link>http://geeks.ms/blogs/etomas/archive/tags/patrones/default.aspx</link><description>Etiquetas: patrones</description><dc:language /><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Promise Pattern</title><link>http://geeks.ms/blogs/etomas/archive/2012/11/16/promise-pattern.aspx</link><pubDate>Fri, 16 Nov 2012 12:28:50 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:207451</guid><dc:creator>Eduard Tomàs i Avellana</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/etomas/rsscomments.aspx?PostID=207451</wfw:commentRss><comments>http://geeks.ms/blogs/etomas/archive/2012/11/16/promise-pattern.aspx#comments</comments><description>&lt;p&gt;¡Buenas! &lt;/p&gt;  &lt;p&gt;Este post está “inspirado” &lt;a href="https://twitter.com/0GiS0/status/268729356761849856" target="_blank"&gt;por un tweet de Gisela Torres&lt;/a&gt;. Posteriormente ella misma &lt;a href="http://www.returngis.net/2012/11/el-patron-promise-y-callback/" target="_blank"&gt;hizo un post en su blog sobre este mismo patrón&lt;/a&gt; que os recomiendo leer.&lt;/p&gt;  &lt;p&gt;Ultimamente está muy de moda, al menos en el mundo de Javascript, hablar del &lt;em&gt;Promise pattern&lt;/em&gt; (lo siento, pero llega un punto en que yo ya desisto de intentar encontrar traducciones para todo…). Ese patrón se asocia mucho con la realización de aplicaciones asíncronas, llegándose a ver como el mecanismo para la realización de este tipo de aplicaciones.&lt;/p&gt;  &lt;p&gt;No. El promise pattern nada tiene que ver con la creación de aplicaciones asíncronas, aunque es en estas, por razones que ahora veremos, donde se puede explotar más. Pero es basicamente un patrón de organización de código. Tampoco es exclusivo de Javascript, por supuesto… De hecho, y para no ser clásicos, vamos a ver un ejemplo de su uso en C#.&lt;/p&gt;  &lt;p&gt;El promise pattern nos ayuda a organizar nuestro código en aquellos casos en que un método recibe como parámetro otro método (en el caso de C# un delegate). Este otro método (o delegate) es usualmente una función de callback, aunque no tiene exactamente porque.&lt;/p&gt;  &lt;p&gt;Vamos a verlo con un ejemplo muy tonto. Imaginad una clase como la siguiente:&lt;/p&gt;  &lt;div style="font-size:10pt;font-family:consolas;background:white;color:black;"&gt;   &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;NoPromise&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;{&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Sumar (&lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt; data, &lt;span style="color:#2b91af;"&gt;Action&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt; next )&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;var&lt;/span&gt; result = 0;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color:blue;"&gt;var&lt;/span&gt; item &lt;span style="color:blue;"&gt;in&lt;/span&gt; data) result += item;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; next(result);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Invertir(&lt;span style="color:blue;"&gt;int&lt;/span&gt; value, &lt;span style="color:#2b91af;"&gt;Action&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt; next)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;var&lt;/span&gt; result = value * -1;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; next(result);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Dividir(&lt;span style="color:blue;"&gt;int&lt;/span&gt; value, &lt;span style="color:blue;"&gt;float&lt;/span&gt; divisor, &lt;span style="color:#2b91af;"&gt;Action&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;float&lt;/span&gt;&amp;gt; next)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;var&lt;/span&gt; result = value/divisor;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; next(result);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin:0px;"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Esta clase expone tres métodos Sumar, Dividir e Invertir. Ambos aceptan un segundo parámetro (un delegate) llamado next que le dice al método &lt;em&gt;que hacer con&lt;/em&gt; el resultado.&lt;/p&gt;  &lt;p&gt;Así podemos invocar dichos métodos así:&lt;/p&gt;  &lt;div style="font-size:10pt;font-family:consolas;background:white;color:black;"&gt;   &lt;p style="margin:0px;"&gt;np.Sumar(list, x =&amp;gt; &lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; np.Invertir(x, y=&amp;gt; &lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; np.Dividir(y, 4.0f, z =&amp;gt; &lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;El resultado es &amp;quot;&lt;/span&gt; + z))));&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Aquí no tenemos asincronidad alguna, simplemente estamos encadenando métodos. Fijaos en como tenemos una “cascada” de funciones encadeandas. La llamada a la primera función (Sumar) tiene en su interior la llamada a Invertir, que en su interior tiene la llamada a Dividir que en su interior tiene el Console.WriteLine. Tenemos pues “una cascada de funciones dentro de funciones”.&lt;/p&gt;  &lt;p&gt;Este problema es el que el promise pattern intenta solucionar… Veamos primero como sería el resultado de las llamadas usando este patrón:&lt;/p&gt;  &lt;div style="font-size:10pt;font-family:consolas;background:white;color:black;"&gt;   &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; prom1 = pd.Sumar(list);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; prom2 = prom1.Then(x =&amp;gt; pd.Invertir(x));&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; prom3 = prom2.Then(x =&amp;gt; pd.Dividir(x, 4.0f));&lt;/p&gt;    &lt;p style="margin:0px;"&gt;prom3.Then(x =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;El valor es &amp;quot;&lt;/span&gt; + x));&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Si preferís podríais usar una sintaxis más compacta sin declarar las variables intermedias:&lt;/p&gt;  &lt;div style="font-size:10pt;font-family:consolas;background:white;color:black;"&gt;   &lt;p style="margin:0px;"&gt;pd.Sumar(list).&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; Then(x =&amp;gt; pd.Invertir(x)).&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; Then(x =&amp;gt; pd.Dividir(x, 4.0f)).&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; Then(x =&amp;gt; &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;final: &amp;quot;&lt;/span&gt; + x));&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;La idea es que el método Sumar &lt;strong&gt;no&lt;/strong&gt; recibe como un parámetro el método a invocar a continuación si no que nos devuelve un objeto (el &lt;em&gt;promise&lt;/em&gt;). A este objeto le podremos indicar (usando el método Then) cual es el siguiente método a invocar. Además los promises se encadenan entre ellos. Fijaos como hemos pasado de una llamada a un método (que dentro tenía varias llamadas más) a cuatro llamadas separadas. Eso mejora mucho la legibilidad del código que es el objetivo principal de este patrón.&lt;/p&gt;  &lt;p&gt;Por si os interesa aquí tenéis la implementación que he usado del patrón. Primero la interfaz:&lt;/p&gt;  &lt;div style="font-size:10pt;font-family:consolas;background:white;color:black;"&gt;   &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;interface&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IPromise&lt;/span&gt;&amp;lt;T&amp;gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;{&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:#2b91af;"&gt;IPromise&lt;/span&gt;&amp;lt;TR&amp;gt; Then&amp;lt;TR&amp;gt;(&lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;T, TR&amp;gt; action);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Then(&lt;span style="color:#2b91af;"&gt;Action&lt;/span&gt;&amp;lt;T&amp;gt; action);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; T Value { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; }&lt;/p&gt;    &lt;p style="margin:0px;"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Y luego la clase que lo implementa:&lt;/p&gt;  &lt;div style="font-size:10pt;font-family:consolas;background:white;color:black;"&gt;   &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Promise&lt;/span&gt;&amp;lt;T&amp;gt; : &lt;span style="color:#2b91af;"&gt;IPromise&lt;/span&gt;&amp;lt;T&amp;gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;{&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;private&lt;/span&gt; T _data;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; Promise(T data)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; _data = data;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IPromise&lt;/span&gt;&amp;lt;TR&amp;gt; Then&amp;lt;TR&amp;gt;(&lt;span style="color:#2b91af;"&gt;Func&lt;/span&gt;&amp;lt;T, TR&amp;gt; action)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Promise&lt;/span&gt;&amp;lt;TR&amp;gt;(action(_data));&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; T Value&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;get&lt;/span&gt;{ &lt;span style="color:blue;"&gt;return&lt;/span&gt; _data; }&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; Then(&lt;span style="color:#2b91af;"&gt;Action&lt;/span&gt;&amp;lt;T&amp;gt; action)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; action(_data);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin:0px;"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Finalmente necesitamos que el método Sumar (que es el iniciador de la cadena de promises) me devuelva un IPromise:&lt;/p&gt;  &lt;div style="font-size:10pt;font-family:consolas;background:white;color:black;"&gt;   &lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;PromiseDemo&lt;/span&gt;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;{&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;IPromise&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt; Sumar(&lt;span style="color:#2b91af;"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt; data)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;var&lt;/span&gt; result = 0;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;foreach&lt;/span&gt; (&lt;span style="color:blue;"&gt;var&lt;/span&gt; item &lt;span style="color:blue;"&gt;in&lt;/span&gt; data) result += item;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Promise&lt;/span&gt;&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;(result);&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;int&lt;/span&gt; Invertir(&lt;span style="color:blue;"&gt;int&lt;/span&gt; value)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;return&lt;/span&gt; value * -1;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;float&lt;/span&gt; Dividir(&lt;span style="color:blue;"&gt;int&lt;/span&gt; value, &lt;span style="color:blue;"&gt;float&lt;/span&gt; div)&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; {&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &lt;span style="color:blue;"&gt;return&lt;/span&gt; value / div;&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; }&lt;/p&gt;    &lt;p style="margin:0px;"&gt;}&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;El resto de métodos son métodos “normales”.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;¿Y porqué (casi) todo el mundo asocia el promise pattern con asincronidad?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Bueno… si os fijáis el promise pattern permite organizar mejor nuestro código en aquellos casos en que un método espera a otro método como parámetro. Y eso es un caso habitual en… las funciones asíncronas que, por norma general, esperan un parámetro adicional que es el callback.&lt;/p&gt;  &lt;p&gt;Ahora imaginad la situación clásica de que el callback de una función asíncrona es a su vez una función asíncrona que espera otro callback que es a su vez otra función asíncrona con otro callback… Llegamos así a la cascada de callbacks dentro de callbacks que es justo el caso que soluciona este patrón. De ahí que la gente asocie promise pattern a asincronidad aunque no tengan nada que ver.&lt;/p&gt;  &lt;p&gt;De hecho .NET, en la TPL tiene una implementación ya realizada del promise pattern… Os suena el método &lt;em&gt;&lt;a href="http://msdn.microsoft.com/es-es/library/dd270696.aspx" target="_blank"&gt;ContinueWith&lt;/a&gt;&lt;/em&gt; de la clase Task? Pues viene a ser una implementación del promise pattern (en este caso la propia clase Task actúa como promise).&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;¿Y porque se habla tanto del promise pattern en Javascript?&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;De hecho más que en javascript deberíamos decir en lenguajes funcionales donde las funciones son ciudadanos de primer orden. En C# hasta la aparición de las expresiones lambda y los delegados genéricos no podíamos implementar este patrón (de una forma cómoda). Por eso en lenguajes no funcionales no se habla mucho de este patrón ya que en estos lenguajes no puede pasarse “una función entera” como parámetro a una función.&lt;/p&gt;  &lt;p&gt;Pero en Javascript si se puede, y la popularidad que está adquiriendo el lenguaje junto con muchos frameworks que tienen este tipo de llamadas hace que la gente empiece a hablar de este patrón.&lt;/p&gt;  &lt;p&gt;Pero insisto: no tiene nada que ver con asincronidad (aunque ahí se use mucho). P.ej. el siguiente código jQuery no tiene nada de asíncrono pero sería un candidato perfecto a utilizarel promise pattern:&lt;/p&gt;  &lt;div style="font-size:10pt;font-family:consolas;background:white;color:black;"&gt;   &lt;p style="margin:0px;"&gt;$(document).ready(&lt;span style="color:blue;"&gt;function&lt;/span&gt;() {&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; $(&lt;span style="color:#a31515;"&gt;&amp;quot;#cmdOpen&amp;quot;&lt;/span&gt;).click(&lt;span style="color:blue;"&gt;function&lt;/span&gt;() {&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $(&lt;span style="color:#a31515;"&gt;&amp;quot;#divData&amp;quot;&lt;/span&gt;).fadeIn(&lt;span style="color:#a31515;"&gt;&amp;quot;slow&amp;quot;&lt;/span&gt;, &lt;span style="color:blue;"&gt;function&lt;/span&gt;() {&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; $(&lt;span style="color:#a31515;"&gt;&amp;quot;#divOther&amp;quot;&lt;/span&gt;).show();&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; });&lt;/p&gt;    &lt;p style="margin:0px;"&gt;&amp;#160;&amp;#160;&amp;#160; });&lt;/p&gt;    &lt;p style="margin:0px;"&gt;});&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;¡Espero que este post sobre este patrón os haya parecido interesante!&lt;/p&gt;  &lt;p&gt;Un saludo!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=207451" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/etomas/archive/tags/patrones/default.aspx">patrones</category></item><item><title>EF4 Code First, MVC2 y Unity para atarlo todo un poco…</title><link>http://geeks.ms/blogs/etomas/archive/2010/09/24/ef4-code-first-mvc2-y-unity-para-atarlo-todo-un-poco.aspx</link><pubDate>Fri, 24 Sep 2010 10:57:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:182398</guid><dc:creator>Eduard Tomàs i Avellana</dc:creator><slash:comments>11</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/etomas/rsscomments.aspx?PostID=182398</wfw:commentRss><comments>http://geeks.ms/blogs/etomas/archive/2010/09/24/ef4-code-first-mvc2-y-unity-para-atarlo-todo-un-poco.aspx#comments</comments><description>&lt;p&gt;Buenas! No soy ni mucho menos un experto en EF (es más, me acabo de poner), como pueda serlo p.ej. &lt;a href="http://geeks.ms/blogs/unai/"&gt;Unai&lt;/a&gt;, pero desde que &lt;a href="http://weblogs.asp.net/scottgu/"&gt;Scott Guthrie&lt;/a&gt; publicó un &lt;a href="http://weblogs.asp.net/scottgu/archive/2010/07/16/code-first-development-with-entity-framework-4.aspx"&gt;post sobre EF Code First&lt;/a&gt; he empezado a mirar algunas cosillas.&lt;/p&gt;  &lt;p&gt;Resumiendo rápidamente EF Code First nos permite desarrollar nuestra capa de acceso a datos codificando &lt;em&gt;primero&lt;/em&gt; las clases, clases que son &lt;a href="http://en.wikipedia.org/wiki/Plain_Old_CLR_Object"&gt;POCO&lt;/a&gt;. Eso nos permite conseguir lo que se conoce como &lt;em&gt;persistance ignorance&lt;/em&gt; (o que las clases que nos representan los datos sean agnósticas sobre cualquier tecnología de acceso a datos).&lt;/p&gt;  &lt;p&gt;Que quede claro que Code First &lt;strong&gt;no&lt;/strong&gt; es la única manera de usar objetos POCO en EF: Unai y Alberto hablan del tema &lt;a href="http://geeks.ms/blogs/unai/archive/2010/01/19/ef-4-0-poco-y-proxies-din-225-micos.aspx"&gt;aquí&lt;/a&gt; y &lt;a href="http://geeks.ms/blogs/adiazmartin/archive/2010/01/17/poco-en-entity-framework-4-0.aspx"&gt;aquí&lt;/a&gt;. Y dad por seguro que ellos conocen EF mucho más que yo :)&lt;/p&gt;  &lt;p&gt;Lo que os quiero comentar es como se puede montar EF Code First en una aplicación MVC2 para poder usar el patrón Repository y Unit Of Work, de forma que los controladores no deban saber nada del mecanismo subyacente de acceso a datos (es decir, los controladores ignoran completamente que están usando EF).&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;1. Rápida, rapidísima introducción a EF Code First&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Usar EF Code First es muy sencillo. En el post de Scott Guthrie está todo explicado paso a paso, pero resumiendo podríamos decir que me puedo crear una clase tal que:&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;background-color:#f4f4f4;margin:0em;border-left-style:none;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;border-right-style:none;font-size:8pt;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; Persona&lt;br /&gt;{&lt;br /&gt;   &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; PersonaId {get; set;}&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;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Esta clase nos permitiría acceder a datos almacenados en una tabla con los campos PersonaId y Nombre (EF Code First es capaz de crear la BBDD a partir del modelo de objetos). Para acceder a la bbdd creamos un objeto derivado de DbContext:&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;background-color:#f4f4f4;margin:0em;border-left-style:none;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;border-right-style:none;font-size:8pt;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; MyDatabase : DbContext&lt;br /&gt;{&lt;br /&gt;   &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; DbSet&amp;lt;Persona&amp;gt; Personas {get; set;}&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Y a partir de aquí instanciamos un objeto MyDatabase y lanzamos consultas linq contra la propiedad Personas… :)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Patrón repositorio y Unit of work&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Esos patrones están explicados por activa y por pasiva en muchos sitios. P.ej. aquí está el &lt;a href="http://martinfowler.com/eaaCatalog/repository.html"&gt;patrón repositorio&lt;/a&gt; y aquí el &lt;a href="http://martinfowler.com/eaaCatalog/unitOfWork.html"&gt;Unit of Work&lt;/a&gt; (UoW). Básicamente entendemos que el repositorio es una colección de objetos en memoria y que el patrón UoW sincroniza todos los cambios hechos en memoria hacia la base de datos.&lt;/p&gt;

&lt;p&gt;Supongamos estos dos interfaces para definir ambos patrones:&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;background-color:#f4f4f4;margin:0em;border-left-style:none;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;border-right-style:none;font-size:8pt;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; IRepository&amp;lt;TEntity&amp;gt; &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; TEntity : &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;    IQueryable&amp;lt;TEntity&amp;gt; AsQueryable();    &lt;br /&gt;    IEnumerable&amp;lt;TEntity&amp;gt; GetAll();&lt;br /&gt;    IEnumerable&amp;lt;TEntity&amp;gt; Find(Expression&amp;lt;Func&amp;lt;TEntity, &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt;);&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&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;background-color:#f4f4f4;margin:0em;border-left-style:none;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;border-right-style:none;font-size:8pt;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; IUnitOfWork&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Commit();&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Mi repositorio es de sólo lectura (no hay métodos Add ni Remove ni nada, pero todo es añadirlos) y el Unit of Work lo único que tiene es el método Commit() para sincronizar los cambios hechos en los repositorios y mandarlos todos a la base de datos.&lt;/p&gt;

&lt;p&gt;EF Code First, implementa de &lt;em&gt;per se&lt;/em&gt; el patrón Unit Of Work (a través de DbContext) y también el patrón repositorio a través de DbSet&amp;lt;&amp;gt;, pero recordad que yo quiero “agnostizarme” al respecto de EF, por eso creo las interfaces y ahora debo crear implementaciones de ellas &lt;em&gt;para EF&lt;/em&gt;:&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;background-color:#f4f4f4;margin:0em;border-left-style:none;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;border-right-style:none;font-size:8pt;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; Repository&amp;lt;TEntity&amp;gt; : IRepository&amp;lt;TEntity&amp;gt; &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; TEntity : &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt;&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; IDbSet&amp;lt;TEntity&amp;gt; _dbSet;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; Repository(IDbContext objectContext)&lt;br /&gt;    {&lt;br /&gt;        _dbSet = objectContext.Set&amp;lt;TEntity&amp;gt;();&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; IQueryable&amp;lt;TEntity&amp;gt; AsQueryable()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; _dbSet;&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; IEnumerable&amp;lt;TEntity&amp;gt; GetAll()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; _dbSet.ToList();&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; IEnumerable&amp;lt;TEntity&amp;gt; Find(Expression&amp;lt;Func&amp;lt;TEntity, &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt;&amp;gt;&amp;gt; &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt;)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; _dbSet.Where(&lt;span style="color:#0000ff;"&gt;where&lt;/span&gt;);&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&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;background-color:#f4f4f4;margin:0em;border-left-style:none;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;border-right-style:none;font-size:8pt;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; UnitOfWork : IUnitOfWork, IDisposable&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;readonly&lt;/span&gt; IDbContext _objectContext;&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; UnitOfWork(IDbContext objectContext)&lt;br /&gt;    {&lt;br /&gt;        _objectContext = objectContext;&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; Dispose()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (_objectContext != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;            _objectContext.Dispose();&lt;br /&gt;        }&lt;br /&gt;        GC.SuppressFinalize(&lt;span style="color:#0000ff;"&gt;this&lt;/span&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; Commit()&lt;br /&gt;    {&lt;br /&gt;        _objectContext.SaveChanges();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;La única “complicación” es en la implementación de &lt;em&gt;UnitOfWork&lt;/em&gt;, que en el constructor uso un objeto de tipo &lt;em&gt;IDbContext&lt;/em&gt;, pero esta interfaz &lt;strong&gt;no existe&lt;/strong&gt; en EF: me la he inventado yo, para poder realizar DI luego cuando use Unity. La interfaz IDbContext es muy simple:&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;background-color:#f4f4f4;margin:0em;border-left-style:none;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;border-right-style:none;font-size:8pt;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; IDbContext : IDisposable&lt;br /&gt;{&lt;br /&gt;    IDbSet&amp;lt;T&amp;gt; Set&amp;lt;T&amp;gt;() &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; T : &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt;;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; SaveChanges();&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Me permite obtener un &lt;em&gt;IDbSet&lt;/em&gt; de entidades de tipo T y el método &lt;em&gt;SaveChanges&lt;/em&gt; para persistir los cambios realizados en este contexto hacia la BBDD.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Uso de todo esto…&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Para usar directamente un repositorio me basta con instanciarlo, pasándole como parámetro el IDbContext. Pero recordad que la clase DbContext de EF Code First &lt;strong&gt;no&lt;/strong&gt; implementa IDbContext (que me lo he inventado yo), así que uso el patrón&lt;em&gt; &lt;a href="http://en.wikipedia.org/wiki/Adapter_pattern"&gt;Adapter&lt;/a&gt;&lt;/em&gt; para &lt;em&gt;traducir &lt;/em&gt;los objetos DbContext a IDbContext:&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;background-color:#f4f4f4;margin:0em;border-left-style:none;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;border-right-style:none;font-size:8pt;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; DbContextAdapter : IDbContext&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;readonly&lt;/span&gt; DbContext _context;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; DbContextAdapter(DbContext context)&lt;br /&gt;    {&lt;br /&gt;        _context = context;&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; Dispose()&lt;br /&gt;    {&lt;br /&gt;        _context.Dispose();&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; IDbSet&amp;lt;T&amp;gt; Set&amp;lt;T&amp;gt;() &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; T : &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt;&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; _context.Set&amp;lt;T&amp;gt;();&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; SaveChanges()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; _context.SaveChanges();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Ahora sí que ya puedo crear un repositorio:&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;background-color:#f4f4f4;margin:0em;border-left-style:none;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;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;IDbContext ctx = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; DbContextAdapter(MyDatabase);  &lt;span style="color:#008000;"&gt;// MyDatabase deriva de DbContext&lt;/span&gt;&lt;br /&gt;var rep = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Repository&amp;lt;Persona&amp;gt;(ctx);&lt;br /&gt;var personas = rep.FindAll();&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Para usar el Unit of Work vinculado a un contexto haríamos lo mismo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Añadiendo IoC a todo esto…&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ahora que ya vemos como podemos usar nuestro repositorio, vamos a ver como Unity nos ayuda a tener IoC y independizarnos realmente de EF.&lt;/p&gt;

&lt;p&gt;Primero podríamos registrar las implementaciones concretas de IRepository y IUnitOfWork:&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;background-color:#f4f4f4;margin:0em;border-left-style:none;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;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#008000;"&gt;// Container es el IUnityContainer&lt;/span&gt;&lt;br /&gt;Container.RegisterType(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(IRepository&amp;lt;&amp;gt;), &lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(Repository&amp;lt;&amp;gt;));&lt;br /&gt;Container.RegisterType&amp;lt;IUnitOfWork, UnitOfWork&amp;gt;();&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Ahora debemos mapear IDbContext a DbContextAdapter (porque para instanciar tanto IRepository como IUnitOfWork les debemos pasar un IDbContext. Podríamos usar lo siguiente:&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;background-color:#f4f4f4;margin:0em;border-left-style:none;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;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;Container.RegisterType&amp;lt;IDbContext, DbContextAdapter&amp;gt;();&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Este RegisterType está bien, pero el problema nos viene cuando vemos que el constructor de DbContextAdapter tiene un objeto &lt;em&gt;DbContext&lt;/em&gt;. Eso significaría que Unity nos crearía un objeto de la clase &lt;strong&gt;DbContext&lt;/strong&gt; y no de la clase derivada MyDatabase, para instanciar los objetos DbContextAdapter. &lt;strong&gt;Nota:&lt;/strong&gt; Una solución sería que la clase DbContextAdapter tuviese en su constructor un objeto que no fuera DbContext sinó MyDatabase pero eso entonces limita la reutilización de todo lo que estamos haciendo!&lt;/p&gt;

&lt;p&gt;Por suerte no estamos perdidos! Unity incorpora un mecanismo mediante el cual le podemos decir &lt;em&gt;como crear&lt;/em&gt; un objeto de una determinada clase. &lt;a href="http://geeks.ms/blogs/etomas/archive/2010/06/02/novedades-de-unity-2-0.aspx"&gt;En mi post sobre Unity 2.0&lt;/a&gt;, hablé de las Injection Factories. La idea es decirle a Unity que cuando necesite un objeto de la clase indicada, en lugar de crearlo tal cual use una factoría nuestra.&lt;/p&gt;

&lt;p&gt;Es decir podemos hacer una factoría para crear DbContext que en lugar de un DbContext devuelva un MyDatabase, y Unity usará dicha factoría cada vez que deba crear un DbContext:&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;background-color:#f4f4f4;margin:0em;border-left-style:none;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;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;Container.RegisterType&amp;lt;DbContext&amp;gt;(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; InjectionFactory(x =&amp;gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; MyDatabase()));&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Listos! Con esto cuando Unity deba pasar a DbContextAdapter un objeto DbContext (como indica el constructor) creará realmente un objeto MyDatabase.&lt;/p&gt;

&lt;p&gt;Ahora si que ya puedo 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;background-color:#f4f4f4;margin:0em;border-left-style:none;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;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;var rep = Container.Resolve&amp;lt;IRepository&amp;lt;Persona&amp;gt;&amp;gt;();&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Y finalmente… MVC2&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Para integrar esto dentro de MVC2 es muy sencillo: como siempre que queramos inyectar IoC en los controladores lo que debemos tocar es… la factoría de controladores:&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;background-color:#f4f4f4;margin:0em;border-left-style:none;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;border-right-style:none;font-size:8pt;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; UnityControllerFactory : DefaultControllerFactory&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;readonly&lt;/span&gt; IUnityContainer _sl;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; UnityControllerFactory(IUnityContainer sl) &lt;br /&gt;    {&lt;br /&gt;        _sl = sl;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; IController GetControllerInstance(RequestContext requestContext, Type controllerType)&lt;br /&gt;    {&lt;br /&gt;        IController controller = _sl.Resolve(controllerType);&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; controller;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Y como siempre establecerla en el Global.asax:&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;background-color:#f4f4f4;margin:0em;border-left-style:none;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;border-right-style:none;font-size:8pt;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;UnityControllerFactory slcf = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; UnityControllerFactory(container);&lt;br /&gt;ControllerBuilder.Current.SetControllerFactory(slcf);&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Y listos! Ahora si que hemos llegado al punto &lt;strong&gt;final&lt;/strong&gt;. Por fin podemos declarar un controlador tal que:&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;background-color:#f4f4f4;margin:0em;border-left-style:none;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;border-right-style:none;font-size:8pt;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; PersonasController : Controller&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; IRepository&amp;lt;Persona&amp;gt; _rep;&lt;br /&gt; &lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; HandController(IRepository&amp;lt;Persona&amp;gt; rep)&lt;br /&gt;    {&lt;br /&gt;        _rep = rep;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Y empezar a trabajar usando el repositorio! :)&lt;/p&gt;

&lt;p&gt;Fijaos que en este punto (el controlador) no tenemos nada que nos ate a EF: el repositorio es una interfaz y las clases que usa el repositorio son objetos POCO.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Y para terminar (pero NO lo menos importante)…&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Cuando trabajamos con aplicaciones web, es recomendable que los contextos de base de datos tengan una duración (lifetime) de request (se les llama objetos per-request): es decir si durante una misma petición se necesitan dos repostorios, estos dos repositorios deben de compartir del contexto de base de datos. Con lo que tenemos ahora &lt;em&gt;no&lt;/em&gt; sucede esto, ya que cada vez que Unity deba crear un Repository&amp;lt;&amp;gt; creará su DbContextAdapter asociado que a su vez creará un DbContext (MyDatabase) &lt;strong&gt;nuevo&lt;/strong&gt;. Ese comportamiento no es el desado.&lt;/p&gt;

&lt;p&gt;Por suerte Unity tiene un mecanismo muy bueno para poder establecer &lt;em&gt;cada cuando&lt;/em&gt; debe el contenedor crear un objeto de un tipo determinado: &lt;a href="http://geeks.ms/blogs/etomas/archive/2009/10/26/lifetime-managers-en-unity-o-191-como-s-233-que-eso-que-me-das-es-un-singleton.aspx"&gt;los lifetime managers&lt;/a&gt;. Una solución es crearse un HttpRequestLifetimeManager, de forma que los objetos sólo persistirán durante la misma petición y usar este lifetime manager cuando hagamos el RegisterType de DbContext.&lt;/p&gt;

&lt;p&gt;En &lt;a title="http://unity.codeplex.com/Thread/View.aspx?ThreadId=38588" href="http://unity.codeplex.com/Thread/View.aspx?ThreadId=38588"&gt;http://unity.codeplex.com/Thread/View.aspx?ThreadId=38588&lt;/a&gt; tenéis una implementación de un &lt;strong&gt;HttpRequestLifetimeManager&lt;/strong&gt;, junto con una interesante aportación sobre el uso (en su lugar) de contenedores hijos que mueran a cada request, que tengan los objetos registrados como singletons y eliminar el contenedor hijo (con Dispose()) al final de cada request. Esto tiene la ventaja de que se llamaría a Dispose() de los objetos contenidos (en esta segunda aproximación es el contendor hijo el que tiene un ciclo de vida per-request).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Referencias&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Los siguientes posts contienen más información al respecto:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href="http://elegantcode.com/2009/12/15/entity-framework-ef4-generic-repository-and-unit-of-work-prototype/"&gt;Entity Framework POCO (EF4): Generic Repository and Unit of Work Prototype&lt;/a&gt;. Este es el post que me ha servido de inspiración y de ayuda. Tiene una continuación (&lt;a href="http://elegantcode.com/2009/12/15/building-a-unity-extension-for-entity-framework-poco-configuration-repository-and-unit-of-work/"&gt;Unity Extension for Entity Framework POCO Configuration, Repository and Unit of Work&lt;/a&gt;) donde comenta el uso de Unity. Estos dos posts son &lt;strong&gt;de lectura imprescindible, &lt;/strong&gt;aunque por un lado haya tenido que modificar algunas cosillas para que funcione con la CTP4 de EF Code first y por otro en el tercer post utilize una StaticFactoryExtension en lugar de una Injection Factory (supongo que usa Unity 1.2 que no soporta Injection Factories). Este tercer post utiliza una aproximación &lt;strong&gt;genial&lt;/strong&gt; que es el uso de una extensión de Unity para configurar todos los mappings para los objetos de EF. Repito: lectura imprescindible.&lt;/li&gt;

  &lt;li&gt;Los posts de Scott Guthrie sobre EF Code First:&lt;/li&gt;

  &lt;ol&gt;
    &lt;li&gt;&lt;a title="http://weblogs.asp.net/scottgu/archive/2010/07/16/code-first-development-with-entity-framework-4.aspx" href="http://weblogs.asp.net/scottgu/archive/2010/07/16/code-first-development-with-entity-framework-4.aspx"&gt;http://weblogs.asp.net/scottgu/archive/2010/07/16/code-first-development-with-entity-framework-4.aspx&lt;/a&gt;&lt;/li&gt;

    &lt;li&gt;&lt;a title="http://weblogs.asp.net/scottgu/archive/2010/07/23/entity-framework-4-code-first-custom-database-schema-mapping.aspx" href="http://weblogs.asp.net/scottgu/archive/2010/07/23/entity-framework-4-code-first-custom-database-schema-mapping.aspx"&gt;http://weblogs.asp.net/scottgu/archive/2010/07/23/entity-framework-4-code-first-custom-database-schema-mapping.aspx&lt;/a&gt;&lt;/li&gt;

    &lt;li&gt;&lt;a title="http://weblogs.asp.net/scottgu/archive/2010/08/03/using-ef-code-first-with-an-existing-database.aspx" href="http://weblogs.asp.net/scottgu/archive/2010/08/03/using-ef-code-first-with-an-existing-database.aspx"&gt;http://weblogs.asp.net/scottgu/archive/2010/08/03/using-ef-code-first-with-an-existing-database.aspx&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;/ol&gt;

&lt;p&gt;Un saludo!!! :)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=182398" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/etomas/archive/tags/patrones/default.aspx">patrones</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/IoC/default.aspx">IoC</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/unity/default.aspx">unity</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/asp.net+MVC/default.aspx">asp.net MVC</category></item><item><title>Caliburn… ¿sientes el poder de MVVM en tus manos?</title><link>http://geeks.ms/blogs/etomas/archive/2010/02/12/caliburn-191-sientes-el-poder-de-mvvm-en-tus-manos.aspx</link><pubDate>Fri, 12 Feb 2010 16:22:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:167258</guid><dc:creator>Eduard Tomàs i Avellana</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/etomas/rsscomments.aspx?PostID=167258</wfw:commentRss><comments>http://geeks.ms/blogs/etomas/archive/2010/02/12/caliburn-191-sientes-el-poder-de-mvvm-en-tus-manos.aspx#comments</comments><description>&lt;p&gt;Los m&amp;aacute;s frikis de por aqu&amp;iacute;, sabr&amp;eacute;is que Caliburn (&lt;em&gt;&lt;a target="_blank" href="http://la.wikipedia.org/wiki/Caliburnus"&gt;Caliburnus&lt;/a&gt;&lt;/em&gt; para ser exactos) era el nombre de una poderosa espada que luego alguien decidi&amp;oacute; rebautizar como &lt;a target="_blank" href="http://es.wikipedia.org/wiki/Excalibur"&gt;&lt;em&gt;Excalibur&lt;/em&gt;&lt;/a&gt;&amp;hellip; Como frikis hay en todas partes y en eso de la inform&amp;aacute;tica pues quiz&amp;aacute;s m&amp;aacute;s, &lt;a target="_blank" href="http://caliburn.codeplex.com/"&gt;Caliburn&lt;/a&gt; tambi&amp;eacute;n resulta ser el nombre de un framework para aplicaciones Silverlight y WPF. Dicho as&amp;iacute; parece ser lo mismo que &lt;a target="_blank" href="http://www.codeplex.com/CompositeWPF/"&gt;PRISM&lt;/a&gt; y en cierta manera ambos frameworks tienen el mismo objetivo y comparten muchas caracter&amp;iacute;sticas. Por ejemplo ambos frameworks se abstraen del contendor IoC a utilizar (es decir requieren uno, pero no se atan a ninguno), ambos dan soporte a vistas compuestas y ambos tienen el concepto de m&amp;oacute;dulo&amp;hellip; entonces &amp;iquest;en que se diferencian? Pues en como se enfocan para llegar al objetivo. El objetivo de este post es &lt;strong&gt;iniciar una serie de posts&lt;/strong&gt; (no se de cuantos :P) para hablar sobre Caliburn y compararlo con PRISM. Hoy, pero vamos a empezar por lo m&amp;aacute;s b&amp;aacute;sico&amp;hellip; :)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Preparando el entorno&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;No es muy complicado preparar el entorno para trabajar con Caliburn: basta con &lt;a target="_blank" href="http://caliburn.codeplex.com/releases/view/34985"&gt;descargarse el framework (actualmente est&amp;aacute; en v1 RTW)&lt;/a&gt;. Caliburn (de nuevo al igual que PRISM) existe en dos sabores: Silverlight y WPF. Ambas versiones son esencialmente la misma salvando las diferencias t&amp;eacute;cnol&amp;oacute;gicas que existen entre Silverlight y WPF. Vamos a optar en este caso por una aplicaci&amp;oacute;n WPF.&lt;/p&gt;
&lt;p&gt;Abrimos VS2008 y creamos una nueva aplicaci&amp;oacute;n WPF. El siguiente paso es a&amp;ntilde;adir referencias a los ensablados de Caliburn que estar&amp;aacute;n en el directorio Bin/NET-3.5/debug (o release, hay ambas versiones). &lt;strong&gt;Nota:&lt;/strong&gt; Yo os recomiendo que os descargueis el codigo fuente y compileis Caliburn&amp;hellip; As&amp;iacute; ser&amp;aacute; m&amp;aacute;s f&amp;aacute;cil depurar! &lt;/p&gt;
&lt;p&gt;Si en lugar de WPF nuestra aplicaci&amp;oacute;n fuese Silverlight entonces debemos ir al directorio Bin/Silverlight-2.0 o Silverlight-3.0 seg&amp;uacute;n sea necesario. Para empezar vamos a usar Caliburn.Core.dll, Caliburn.PresentationFramework.dll y Microsoft.Practices.ServiceLocation.dll.&lt;/p&gt;
&lt;p&gt;Ahora s&amp;iacute;! Ya estamos listos para desenvainar la espada &amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Empezando con Caliburn&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Caliburn tiene una idea muy clara sobre como se debe organizar la IU de tu aplicaci&amp;oacute;n: usando MVVM. Eso significa que vamos a tener un grupo de clases llamadas &lt;em&gt;ViewModels&lt;/em&gt; que van a ser los que tengan &lt;strong&gt;toda&lt;/strong&gt; la informaci&amp;oacute;n sobre los datos a mostrar. A cada &lt;em&gt;ViewModel&lt;/em&gt; le corresponder&amp;aacute; una vista (&lt;em&gt;View&lt;/em&gt;). El enlace entre las vistas y los &lt;em&gt;ViewModels&lt;/em&gt; ser&amp;aacute; a trav&amp;eacute;s de Bindings&amp;hellip; por supuesto que todo esto se puede hacer sin Caliburn, pero Caliburn nos da herramientas para que sea un poco m&amp;aacute;s f&amp;aacute;cil.&lt;/p&gt;
&lt;p&gt;Para empezar vamos a crear un ViewModel y una vista y vamos a dejar que la magia de Caliburn nos lo una. Para ello, &lt;strong&gt;creamos una carpeta llamada ViewModel&lt;/strong&gt; en nuestro proyecto. Es importante el nombre de esta carpeta, puesto que Caliburn asume que lo que en ella est&amp;eacute; son ViewModels o vistas. Dentro de dicha carpeta creamos una clase tal y como 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;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; UserViewModel&lt;br /&gt;{&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;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Foto { get; set; }&lt;br /&gt;}&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;Ya tenemos el ViewModel de un usuario: su nombre y su foto. Ahora el siguiente paso es crear una vista. Para ello a&amp;ntilde;adid un &lt;em&gt;User Control&lt;/em&gt; que se llame UserView. El nombre de nuevo es importante: Caliburn asumir&amp;aacute; que UserView es la vista para los &lt;em&gt;ViewModels&lt;/em&gt; de tipo UserViewModel. Poned el user control &lt;strong&gt;fuera&lt;/strong&gt; de la carpeta ViewModel. El c&amp;oacute;digo xaml puede ser algo parecido a:&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;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;UserControl&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;x:Class&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;CaliburnDemo.UserView&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#ff0000;"&gt;xmlns&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#ff0000;"&gt;xmlns:x&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#ff0000;"&gt;Height&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;300&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Width&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;300&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Grid&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Label&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Height&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;28&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Margin&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;25,47,28,0&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;VerticalAlignment&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;Top&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Content&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;{Binding Nombre}&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Label&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Image&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Margin&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;109,81,127,0&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Stretch&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;Fill&amp;quot;&lt;/span&gt;  &lt;span style="color:#ff0000;"&gt;Width&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;64&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Height&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;64&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;VerticalAlignment&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;Top&amp;quot;&lt;/span&gt; &lt;br /&gt;               &lt;span style="color:#ff0000;"&gt;Source&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;{Binding Foto}&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Label&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Height&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;28&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;Margin&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;85,13,101,0&amp;quot;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;VerticalAlignment&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;Top&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;Datos del Usuario:&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Label&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Grid&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;UserControl&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;Finalmente s&amp;oacute;lo nos queda un paso: modificar nuestra aplicaci&amp;oacute;n para que derive de &lt;em&gt;CaliburnApplication&lt;/em&gt;. Para ello, en App.cs modificad la clase para que derive de CaliburnApplication:&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;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;partial&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; App : CaliburnApplication&lt;br /&gt;{&lt;br /&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; CreateRootModel()&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; UserViewModel();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;Fijaos que redefinimos el m&amp;eacute;todo CreateRootModel: Este m&amp;eacute;todo (definido en CaliburnApplication) es el punto de entrada de nuestra aplicaci&amp;oacute;n. El tipo de ViewModel que creemos determinar&amp;aacute; el tipo de vista a utilizar y los datos iniciales a mostrar. Un detalle: Fijaos que &lt;strong&gt;no&lt;/strong&gt; vamos a crear una ventana nunca (nuestra vista UserView es un UserControl). No hay problema, porque si el ViewModel inicial no es una ventana, Caliburn la va a crear para nosotros.&lt;/p&gt;
&lt;p&gt;Hemos modificado la clase base de la aplicaci&amp;oacute;n en el fichero .cs y debemos hacer lo mismo en App.xaml:&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;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;caliburn:CaliburnApplication&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;x:Class&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;CaliburnDemo.App&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#ff0000;"&gt;xmlns&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#ff0000;"&gt;xmlns:x&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;http://schemas.microsoft.com/winfx/2006/xaml&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#ff0000;"&gt;xmlns:caliburn&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;=&amp;quot;clr-namespace:Caliburn.PresentationFramework.ApplicationModel;assembly=Caliburn.PresentationFramework&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;Application.Resources&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;Application.Resources&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;caliburn:CaliburnApplication&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;No hay secreto: Declaro el namespace &lt;em&gt;caliburn&lt;/em&gt; y modifico el tag raiz para que en lugar de Application sea CaliburnApplication que es nuestra nueva clase base. Tambi&amp;eacute;n elimino el StartupUri ya que no es necesario.&lt;/p&gt;
&lt;p&gt;Y listos&amp;hellip; ya podemos ejecutar!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Plaf! La primera en la frente!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Si has seguido mis indicaciones te vas a encontrar algo parecido a esto (si no has compilado Caliburn quiz&amp;aacute; simplemente te salga una excepci&amp;oacute;n en lugar de esta &amp;ldquo;preciosa&amp;rdquo; ventana).&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/image_5F00_46BB08FA.png"&gt;&lt;img height="149" width="345" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/image_5F00_thumb_5F00_761951F9.png" alt="image" border="0" title="image" style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Hombre&amp;hellip; no es muy bonito que digamos&amp;hellip; cual es el problema? F&amp;aacute;cil: la vista no est&amp;aacute; situada en el lugar que toca&amp;hellip; Record&amp;aacute;is que os dije que la pusierais &lt;em&gt;&lt;strong&gt;fuera&lt;/strong&gt; &lt;/em&gt;de la carpeta ViewModel? Pues debe ir dentro&amp;hellip; As&amp;iacute;, que moved UserView &lt;em&gt;dentro&lt;/em&gt; de la carpeta ViewModel y &lt;strong&gt;modificad&lt;/strong&gt; el namespace para que incluya ViewModel:&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;namespace&lt;/span&gt; CaliburnDemo.&lt;strong&gt;&lt;span style="text-decoration:underline;"&gt;ViewModel&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;{&lt;br /&gt;}&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;De hecho lo importante es el namespace, no la ubicaci&amp;oacute;n f&amp;iacute;sica del archivo xaml, as&amp;iacute; que si no quereis moverlo no lo hag&amp;aacute;is per el namespace de la clase UserView debe ser el mismo que el de UserViewModel.&lt;/p&gt;
&lt;p&gt;Ahora s&amp;iacute; que s&amp;iacute;! Si ejecutamos vemos una triste ventana&amp;hellip; pero es &lt;em&gt;nuestra&lt;/em&gt; ventana:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/image_5F00_092A58D9.png"&gt;&lt;img height="244" width="228" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/image_5F00_thumb_5F00_63C0656A.png" alt="image" border="0" title="image" style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Est&amp;aacute; vac&amp;iacute;a porque el ViewModel que hemos creado lo est&amp;aacute;, pero eso tiene f&amp;aacute;cil arreglo modificando el m&amp;eacute;todo &lt;em&gt;CreateRootModel&lt;/em&gt; para que el UserViewModel creado tenga datos:&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;protected&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; CreateRootModel()&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; UserViewModel()&lt;br /&gt;    {&lt;br /&gt;        Nombre = &lt;span style="color:#006080;"&gt;&amp;quot;Edu&amp;quot;&lt;/span&gt;,&lt;br /&gt;        Foto = &lt;span style="color:#006080;"&gt;&amp;quot;/CaliburnDemo;component/avatar.png&amp;quot;&lt;/span&gt;&lt;br /&gt;    };&lt;br /&gt;}&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;(La foto est&amp;aacute; a&amp;ntilde;adida como Resource en el proyecto, de ah&amp;iacute; esta ruta).&lt;/p&gt;
&lt;p&gt;Ahora si que vemos ya nuestros datos:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/image_5F00_06A1271B.png"&gt;&lt;img height="167" width="244" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/image_5F00_thumb_5F00_0C0F97BF.png" alt="image" border="0" title="image" style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&amp;iexcl;Mola! Que es lo que ha hecho Caliburn por nosotros? Pues a partir de un ViewModel ha creado la vista correspondiente y ha asignado el ViewModel como DataContext de la vista&amp;hellip; &lt;/p&gt;
&lt;p&gt;Ok&amp;hellip; no es nada que no podamos hacer nosotros mismos con pocas l&amp;iacute;neas de c&amp;oacute;digo&amp;hellip; pero esto es s&amp;oacute;lo el principio! En sucesivos posts iremos viendo otras cosillas de Caliburn. Obviamente si alguien ha trabajado con Caliburn y/o con PRISM y quiere contar sus opiniones&amp;hellip; adelante!&lt;/p&gt;
&lt;p&gt;Un saludo a todos!&lt;/p&gt;
&lt;p&gt;PD: Dejo el &lt;a target="_blank" href="http://cid-6521c259e9b1bec6.skydrive.live.com/self.aspx/BurbujasNet/ZipsPosts/CaliburnDemo1.zip"&gt;c&amp;oacute;digo del proyecto en este ficherillo zip!&lt;/a&gt; (en mi skydrive)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=167258" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/etomas/archive/tags/wpf/default.aspx">wpf</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/patrones/default.aspx">patrones</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/prism/default.aspx">prism</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/caliburn/default.aspx">caliburn</category></item><item><title>Objetos que notifican sus cambios de propiedades (2/3): Publish and subscribe</title><link>http://geeks.ms/blogs/etomas/archive/2010/01/14/objetos-que-notifican-sus-cambios-de-propiedades-2-3-publish-and-subscribe.aspx</link><pubDate>Thu, 14 Jan 2010 09:04:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:164974</guid><dc:creator>Eduard Tomàs i Avellana</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/etomas/rsscomments.aspx?PostID=164974</wfw:commentRss><comments>http://geeks.ms/blogs/etomas/archive/2010/01/14/objetos-que-notifican-sus-cambios-de-propiedades-2-3-publish-and-subscribe.aspx#comments</comments><description>&lt;p&gt;&lt;strong&gt;Nota: &lt;/strong&gt;Este post es el segundo post de la &lt;a target="_blank" href="http://geeks.ms/blogs/etomas/archive/2010/01/12/objetos-que-notifican-sus-cambios-de-propiedades-0-3-introducci-243-n.aspx"&gt;serie Objetos que notifican sus cambios de propiedades&lt;/a&gt;&lt;em&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;En el post anterior vimos como configurar Unity para que no tener que a&amp;ntilde;adir c&amp;oacute;digo adicional para implementar la interfaz &lt;a target="_blank" href="http://msdn.microsoft.com/es-es/library/system.componentmodel.inotifypropertychanged.aspx"&gt;INotifyPropertyChanged&lt;/a&gt;. En este post quiero hablaros de un patr&amp;oacute;n que se utiliza mucho cuando hablamos de aplicaciones &lt;em&gt;complejas&lt;/em&gt;: el patr&amp;oacute;n del &lt;a target="_blank" href="http://en.wikipedia.org/wiki/Publish/subscribe"&gt;publicador &amp;ndash; suscriptor&lt;/a&gt;. En este patr&amp;oacute;n tenemos b&amp;aacute;sicamente dos conceptos:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;El publicador: Cuando un objeto quiere &lt;em&gt;notificar&lt;/em&gt; algo al respecto de su estado, se limita a publicar un mensaje con la informaci&amp;oacute;n deseada.&lt;/li&gt;
&lt;li&gt;El suscriptor: Los subscriptores reciben todos aquellos mensajes a los que est&amp;aacute;n suscritos, con &lt;em&gt;independencia&lt;/em&gt; de quien los haya publicado.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Este patr&amp;oacute;n se diferencia del modelo de eventos est&amp;aacute;ndard de .NET, en que para realizar una suscripci&amp;oacute;n a un tipo de mensaje no es necesario tener referencia alguna a quien pueda publicar este mensaje. En el sistema de eventos no &amp;eacute;s as&amp;iacute;: si quiero recibir informaci&amp;oacute;n sobre el click de un bot&amp;oacute;n, debo tener &lt;em&gt;una referencia&lt;/em&gt; a este bot&amp;oacute;n, para poder registrar la funci&amp;oacute;n gestora del evento:&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;button1.Click += &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; EventHandler(button1_Click);&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;Este modelo de eventos directos tiene sus limitaciones y da en Winforms bastantes quebraderos de cabeza (especialmente cuando tenemos un formulario con un usercontrol formado por varios usercontrols que a su vez est&amp;aacute;n formados por m&amp;aacute;s usercontrols y queremos propagar un evento del usercontrol&amp;nbsp; m&amp;aacute;s &lt;em&gt;interno&lt;/em&gt; al formulario). Es cierto que WPF introduce dos mejoras interesantes como los &lt;em&gt;&lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/ms742806.aspx"&gt;routed events&lt;/a&gt;&lt;/em&gt; (que ayudan precisamente a solventar este problema de usercontrols anidados) y los &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/ms752308.aspx"&gt;&lt;em&gt;commands&lt;/em&gt;&lt;/a&gt;,&lt;em&gt;&amp;nbsp;&lt;/em&gt;pero ninguno de ambos mecanismos ofrece la misma flexibilidad que el modelo de publicaci&amp;oacute;n &amp;ndash; suscripci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;Cr&amp;eacute;eme: si desarrollas una aplicaci&amp;oacute;n compleja, ya sea en winforms o en WPF, te beneficiar&amp;aacute; mucho el uso de un modelo de publicaci&amp;oacute;n &amp;ndash; suscripci&amp;oacute;n (no en vano tanto CAB+SCSF como PRISM incorporan uno).&lt;/p&gt;
&lt;p&gt;Vamos a ver como podemos implementarnos uno que, aunque sencillito, sea lo suficientemente funcional&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. El notificador de mensajes&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Lo primero que debemos crear es el notificador de mensajes, es decir el objeto que usamos para &lt;em&gt;publicar&lt;/em&gt; un mensaje y el que usamos tambi&amp;eacute;n para informar a que tipo de mensajes queremos &lt;em&gt;suscribirnos&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;El notificador de mensajes va a tener esta interfaz:&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;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;interface&lt;/span&gt; ICommandNotifier&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#008000;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;/// Devuelve la lista de los commands actuales. Los commands se&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;/// a&amp;ntilde;aden autom&amp;aacute;ticamente cuando se realiza un publish de cualquier&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;/// tipo nuevo.&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    IEnumerable&amp;lt;Type&amp;gt; Commands { get; }&lt;br /&gt;    &lt;span style="color:#008000;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;/// A&amp;ntilde;ade una suscripci&amp;oacute;n al tipo de command TPayload&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;/// &amp;lt;typeparam name=&amp;quot;TPayload&amp;quot;&amp;gt;Tipo de command al que nos suscribimos&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;/// &amp;lt;param name=&amp;quot;func&amp;quot;&amp;gt;Acci&amp;oacute;n a ejecutar cuando se publique el command&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;/// &amp;lt;param name=&amp;quot;filterFunc&amp;quot;&amp;gt;M&amp;eacute;todo que se eval&amp;uacute;a sobre el payload para determinar&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;/// si el command se pasa o no al suscriptor.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;/// &amp;lt;returns&amp;gt;Token de suscripci&amp;oacute;n&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;br /&gt;    SubscriptionToken Subscribe&amp;lt;TPayload&amp;gt;(Action&amp;lt;TPayload&amp;gt; func, Func&amp;lt;TPayload, &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt;&amp;gt; filterFunc);&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;/// Publica un command. El tipo de command es el tipo de la clase del payload.&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;/// &amp;lt;param name=&amp;quot;payload&amp;quot;&amp;gt;Payload (datos) del commanad&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Publish(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; payload);&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;B&amp;aacute;sicamente s&amp;oacute;lo tiene un m&amp;eacute;todo para suscribirse a un determinado tipo de mensajes y otro m&amp;eacute;todo para publicarlos. Una implementaci&amp;oacute;n m&amp;aacute;s compleja nos permitir&amp;iacute;a tambi&amp;eacute;n eliminar suscripciones (es decir cuando ya no me interesa seguir recibiendo notificaciones de determinados commands)&amp;hellip; pero eso lo dejamos como ejercicio :)&lt;/p&gt;
&lt;p&gt;La implementaci&amp;oacute;n tampoco es excesivamente compleja (no pongo el c&amp;oacute;digo aqu&amp;iacute;, ya que lo ten&amp;eacute;is en el zip que adjunto al final del post). B&amp;aacute;sicamente lo que hace es:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Mantiene una lista de todos los tipos de mensajes que se hayan lanzado. Lo que determina si un mensaje es de un tipo u otro es su clase (en la implementaci&amp;oacute;n una lista de objetos CommandInfo).&lt;/li&gt;
&lt;li&gt;Por cada mensaje de esa lista mantiene una lista con todos los suscriptores (en la implementaci&amp;oacute;n objetos de la clase AllTimeSubscriber).&lt;/li&gt;
&lt;li&gt;Por cada suscriptor de cada mensaje mantiene b&amp;aacute;sicamente dos delegates:&lt;ol&gt;
&lt;li&gt;El delegate que sirve para decidir si se env&amp;iacute;a este mensaje a este suscriptor (par&amp;aacute;metro &lt;em&gt;filterFunc&lt;/em&gt; del m&amp;eacute;todo Subscribe)&lt;/li&gt;
&lt;li&gt;El delegate que debe invocarse en el suscriptor (par&amp;aacute;metro &lt;em&gt;func&lt;/em&gt; del m&amp;eacute;todo Subscribe).&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;S&amp;oacute;lo un apunte: el notificador de mensajes vamos a registrarlo en Unity como un singleton, eso significa que existir&amp;aacute; s&amp;oacute;lo uno y que estar&amp;aacute; vivo durante &lt;strong&gt;toda&lt;/strong&gt; la ejecuci&amp;oacute;n del programa. Por lo tanto, si guardamos directamente los delegates en el notificador de mensajes, impedir&amp;aacute; al garbage collector actuar sobre los suscriptores (recordad que un delegate mantiene una &lt;em&gt;referencia&lt;/em&gt; a un &lt;em&gt;objeto en concreto&lt;/em&gt; y a un m&amp;eacute;todo). Para solucionar esto me he creado una clase, que he llamado WeakDelegate, que tiene la misma informaci&amp;oacute;n que un delegate, pero usa una &lt;a target="_blank" href="http://msdn.microsoft.com/es-es/library/system.weakreference.aspx"&gt;WeakReference&lt;/a&gt; para apuntar al objeto (el suscriptor) y de esta manera permitir actuar al garbage collector. Recordad: siempre que guardeis referencias en un singleton considerad el uso de WeakReference!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Cambiar la implementaci&amp;oacute;n de nuestro handler&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Una vez tenemos un notificador de mensajes, s&amp;oacute;lo debemos cambiar la implementaci&amp;oacute;n de nuestro &lt;em&gt;ICallHandler&lt;/em&gt; (clase &lt;em&gt;AutoPropertyChangedHandler&lt;/em&gt;) de Unity, para usar dicho notificador. Para ello en el m&amp;eacute;todo &lt;em&gt;Invoke&lt;/em&gt; en lugar de llamar al m&amp;eacute;todo RaiseEvent (para lanzar el evento PropertyChanged) como hac&amp;iacute;amos en el post anterior, vamos a usar el notificador para publicar un mensaje de tipo &lt;em&gt;PropertyChangedCommand&lt;/em&gt;:&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:#008000;"&gt;// Si el setter no produce excepci&amp;oacute;n, publicamos un command de tipo PropertyChangedCommand&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (raiseEvt &amp;amp;&amp;amp; msg.Exception == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;{&lt;br /&gt;    cmdNotifier.Publish(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; PropertyChangedCommand(propName, input.Target));&lt;br /&gt;}&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;La clase PropertyChangedCommand es una clase que nos hemos creado nosotros que no hace nada m&amp;aacute;s que guardar el nombre de la propiedad que ha cambiado y el objeto sobre el cual ha cambiado la propiedad.&lt;/p&gt;
&lt;p&gt;Como recibe la clase AutoPropertyChangedHandler el notificador de mensajes? Pues se le pasa en el constructor:&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;public&lt;/span&gt; AutoPropertyChangedHandler(ICommandNotifier cmdNotifier)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.cmdNotifier = cmdNotifier;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;Ahora s&amp;oacute;lo debemos modificar la clase &lt;em&gt;AutoPropertyChangedAttribute&lt;/em&gt; para que cuando cree el objeto AutoPropertyChangedHandler&amp;nbsp; le pase el notificador de mensajes. La forma m&amp;aacute;s f&amp;aacute;cil es aprovechar que en AutoPropertyChangedAttribute tenemos acceso a Unity, para devolver el objeto AutoPropertyChangedHandler usando Resolve y que de esa manera Unity inyecte el notificador de mensajes:&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;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; ICallHandler CreateHandler(IUnityContainer container)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; container.Resolve&amp;lt;AutoPropertyChangedHandler&amp;gt;();&lt;br /&gt;}&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;3. El suscriptor&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Finalmente nos queda crear el suscriptor. Los suscriptores son clases normales que usan el notificador de mensajes para suscribirse a tipos de mensajes. P.ej. el siguiente suscriptor se suscribe a los mensajes cuyo tipo sea PropertyChangedCommand:&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;public&lt;/span&gt; Suscriptor(ICommandNotifier cmdNotif)&lt;br /&gt;{&lt;br /&gt;    cmdNotif.Subscribe&amp;lt;PropertyChangedCommand&amp;gt;(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.DoPropertyChangedCommand, &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.CanDoPropertyChangedCommand);&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; DoPropertyChangedCommand(PropertyChangedCommand payload)&lt;br /&gt;{&lt;br /&gt;    Console.WriteLine(&lt;span style="color:#006080;"&gt;&amp;quot;Propiedad {0} modificada&amp;quot;&lt;/span&gt;, payload.PropertyName);&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;bool&lt;/span&gt; CanDoPropertyChangedCommand(PropertyChangedCommand payload)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; retVal = !payload.PropertyName.Equals(&lt;span style="color:#006080;"&gt;&amp;quot;Name&amp;quot;&lt;/span&gt;);&lt;br /&gt;    Console.WriteLine(&lt;span style="color:#006080;"&gt;&amp;quot;CanDoPropertyChanged con prop {0} devuelve {1}&amp;quot;&lt;/span&gt;, payload.PropertyName, retVal);&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; retVal;&lt;br /&gt;}&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;F&amp;iacute;ajos en la funci&amp;oacute;n &lt;em&gt;CanDoPropertyChangedCommand&lt;/em&gt;: esta funci&amp;oacute;n se eval&amp;uacute;a cada vez que alguien publica un command y s&amp;oacute;lo en el caso que devuelva &lt;em&gt;true&lt;/em&gt; se ejecutar&amp;aacute; la funci&amp;oacute;n &lt;em&gt;DoPropertyChangedCommand&lt;/em&gt; que es la que &amp;ldquo;procesa&amp;rdquo; el mensaje. En este caso, este suscriptor est&amp;aacute; interesado en recibir todos los cambios de calquier propiedad excepto &amp;ldquo;Name&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Finalmente s&amp;oacute;lo nos queda crear un suscriptor y probar el c&amp;oacute;digo. En el m&amp;eacute;todo Main() tengo:&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;container.RegisterType&amp;lt;ICommandNotifier, CommandNotifier&amp;gt;(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ContainerControlledLifetimeManager());&lt;br /&gt;A2 a2 = container.Resolve&amp;lt;A2&amp;gt;();&lt;br /&gt;Suscriptor subs = container.Resolve&amp;lt;Suscriptor&amp;gt;();&lt;br /&gt;a2.Name = &lt;span style="color:#006080;"&gt;&amp;quot;edu&amp;quot;&lt;/span&gt;;&lt;br /&gt;a2.Edad = 10;&lt;br /&gt;&lt;span style="color:#008000;"&gt;// Registramos el notificador como singleton&lt;/span&gt;&lt;br /&gt;container.RegisterType&amp;lt;ICommandNotifier, CommandNotifier&amp;gt;(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ContainerControlledLifetimeManager());&lt;br /&gt;&lt;span style="color:#008000;"&gt;// Creamos un A2...&lt;/span&gt;&lt;br /&gt;A2 a2 = container.Resolve&amp;lt;A2&amp;gt;();&lt;br /&gt;&lt;span style="color:#008000;"&gt;// ... y un suscriptor&lt;/span&gt;&lt;br /&gt;Suscriptor subs = container.Resolve&amp;lt;Suscriptor&amp;gt;();&lt;br /&gt;a2.Name = &lt;span style="color:#006080;"&gt;&amp;quot;edu&amp;quot;&lt;/span&gt;;&lt;br /&gt;a2.Edad = 10;&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;Y listos! S&amp;iacute; lo ejecutais ver&amp;eacute;is que la salida es:&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;CanDoPropertyChanged con prop Name devuelve False &lt;br /&gt;CanDoPropertyChanged con prop Edad devuelve True &lt;br /&gt;Propiedad Edad modificada&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Ya tenemos implementado nuestro propio publicador-suscriptor!&lt;/p&gt;
&lt;p&gt;Os dejo &lt;a target="_blank" href="http://cid-6521c259e9b1bec6.skydrive.live.com/self.aspx/BurbujasNet/ZipsPosts/AutoNotifPropertiesPost2.zip"&gt;un zip con todo el c&amp;oacute;digo&lt;/a&gt; (en skydrive).&lt;/p&gt;
&lt;p&gt;Un saludo!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=164974" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/etomas/archive/tags/patrones/default.aspx">patrones</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/IoC/default.aspx">IoC</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/unity/default.aspx">unity</category></item><item><title>Objetos que notifican sus cambios de propiedades (1/3): La intercepción</title><link>http://geeks.ms/blogs/etomas/archive/2010/01/13/objetos-que-notifican-sus-cambios-de-propiedades-1-3-la-intercepci-243-n.aspx</link><pubDate>Wed, 13 Jan 2010 12:35:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:164919</guid><dc:creator>Eduard Tomàs i Avellana</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/etomas/rsscomments.aspx?PostID=164919</wfw:commentRss><comments>http://geeks.ms/blogs/etomas/archive/2010/01/13/objetos-que-notifican-sus-cambios-de-propiedades-1-3-la-intercepci-243-n.aspx#comments</comments><description>&lt;p&gt;&lt;strong&gt;Nota:&lt;/strong&gt; Este post es el primer post de la &lt;a target="_blank" href="http://geeks.ms/blogs/etomas/archive/2010/01/12/objetos-que-notifican-sus-cambios-de-propiedades-0-3-introducci-243-n.aspx"&gt;serie Objetos que notifican sus cambios de propiedades&lt;/a&gt;&lt;em&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;En este post vamos a ver como configurar la intercepci&amp;oacute;n de Unity, para poder inyectar nuestro c&amp;oacute;digo cada vez que se modifiquen las propiedades de un objeto.&lt;/p&gt;
&lt;p&gt;Los que desarroll&amp;eacute;is en WPF sabr&amp;eacute;is que existe una interfaz llamada &lt;a target="_blank" href="http://msdn.microsoft.com/es-es/library/system.componentmodel.inotifypropertychanged.aspx"&gt;INotifyPropertyChanged&lt;/a&gt;, que se puede implementar para notificar a la interfaz de usuario de que las propiedades de un objeto (generalmente ligado a la interfaz) han modificado, y que por lo tanto la interfaz debe actualizar sus datos.&lt;/p&gt;
&lt;p&gt;Esta interfaz define un solo evento, llamado &lt;a target="_blank" href="http://msdn.microsoft.com/es-es/library/system.componentmodel.inotifypropertychanged.propertychanged.aspx"&gt;PropertyChanged&lt;/a&gt; que debe lanzarse para informar del cambio de propiedad. Es responsabilidad de cada clase lanzar el evento cuando sea oportuno:&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;public class&lt;/span&gt; A : INotifyPropertyChanged&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; _name;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;// Evento definido por la interfaz&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;event&lt;/span&gt; PropertyChangedEventHandler PropertyChanged;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;// Lanza el evento &amp;quot;PropertyChanged&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; NotifyPropertyChanged(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; info)&lt;br /&gt;    {&lt;br /&gt;        var handler = &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.PropertyChanged;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (handler != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;            handler(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; PropertyChangedEventArgs(info));&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color:#008000;"&gt;// Propiedad que informa de sus cambios&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Name&lt;br /&gt;    {&lt;br /&gt;        get { &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; _name; }&lt;br /&gt;        set&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (_name != &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;)&lt;br /&gt;            {&lt;br /&gt;                _name = &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;;&lt;br /&gt;                NotifyPropertyChanged(&lt;span style="color:#006080;"&gt;&amp;quot;Name&amp;quot;&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;Este c&amp;oacute;digo es pesado de realizar en clases con muchas propiedades y es f&amp;aacute;cil cometer errores&amp;hellip; adem&amp;aacute;s no podemos utilizar las auto-propiedades. Vamos a ver como con el sistema de intercepci&amp;oacute;n de Unity podemos hacer que este evento se lance de forma &lt;em&gt;autom&amp;aacute;tica&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Configurando el sistema de intercepci&amp;oacute;n de Unity&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Para usar el sistema de intercepci&amp;oacute;n de Unity, deb&amp;eacute;is a&amp;ntilde;adir los assemblies Microsoft.Practices.ObjectBuilder2, Microsoft.Practices.Unity y Microsoft.Practices.Unity.Interception a vuestro proyecto (los tres assemblies forman parte de &lt;a target="_blank" href="http://www.codeplex.com/unity/"&gt;Unity&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;El primer paso es crear una clase que implemente la interfaz &lt;em&gt;ICallHandler&lt;/em&gt;, esta clase es la encargada de proporcionarnos un punto d&amp;oacute;nde inyectar el c&amp;oacute;digo:&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;class&lt;/span&gt; AutoPropertyChangedHandler : ICallHandler&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#008000;"&gt;// Aqu&amp;iacute; podremos inyectar nuestro c&amp;oacute;digo&lt;/span&gt;&lt;br /&gt;        IMethodReturn msg = getNext()(input, getNext);&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; msg;&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; Order { get; set; }&lt;br /&gt;}&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;El siguiente paso es crear un atributo que permita indicar a Unity que ICallHandler debe usar cuando se opere con objetos de la clase. Esta clase debe derivar de &lt;em&gt;HandlerAttribute&lt;/em&gt; y debe redefinir el m&amp;eacute;todo &lt;em&gt;CreateHandler&lt;/em&gt; para devolver una instancia del ICallHandler a utilizar:&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;class&lt;/span&gt; AutoPropertyChangedAttribute : HandlerAttribute&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; ICallHandler CreateHandler(IUnityContainer container)&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; AutoPropertyChangedHandler();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;El c&amp;oacute;digo es trivial, eh?? Simplemente devuelve un &lt;em&gt;AutoPropertyChangeHandler&lt;/em&gt;, de esa manera Unity usar&amp;aacute; este AutoPropertyChangeHandler para todas las clases que est&amp;eacute;n decoradas con el atributo &lt;em&gt;AutoPropertyChangedAttribute&lt;/em&gt;. De esta manera es como le indicamos a Unity qu&amp;eacute; ICallHandler debe usar por cada tipo de clase.&lt;/p&gt;
&lt;p&gt;Finalmente queda configurar el propio contenedor. Para ello debemos debemos a&amp;ntilde;adir la extensi&amp;oacute;n de intercepci&amp;oacute;n a Unity y indicarle que interceptor queremos utilizar para cada clase:&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;IUnityContainer container = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; UnityContainer();&lt;br /&gt;container.AddNewExtension&amp;lt;Interception&amp;gt;();&lt;br /&gt;container.Configure&amp;lt;Interception&amp;gt;().SetInterceptorFor&amp;lt;A2&amp;gt;(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; VirtualMethodInterceptor());&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;Le he indicado a Unity que para la clase A2 utilice el interceptor VirtualMethodInterceptor. Este interceptor puede interceptar todas las llamadas a m&amp;eacute;todos virtuales.&lt;/p&gt;
&lt;p&gt;Finalmente ya podemos definir la clase A2:&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;[AutoPropertyChanged()]&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;public class&lt;/span&gt; A2 : INotifyPropertyChanged&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;event&lt;/span&gt; PropertyChangedEventHandler PropertyChanged;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;virtual&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Name { get; set; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;Fijaos en las diferencias entre A2 y la clase A antigua:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A2 est&amp;aacute; decorada con el atributo &lt;em&gt;AutoPropertyChangedAttribute&lt;/em&gt; que hemos definido antes.&lt;/li&gt;
&lt;li&gt;La propiedad Name es &lt;strong&gt;virtual&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;No tenemos ning&amp;uacute;n c&amp;oacute;digo adicional para lanzar el evento PropertyChanged.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Con eso el mecanismo de intercepci&amp;oacute;n est&amp;aacute; listo. Si obteneis una instancia de A2 usando el m&amp;eacute;todo Resolve del contenedor y mir&amp;aacute;is con el debugger de que tipo &lt;em&gt;real&lt;/em&gt; es el objeto, ver&amp;eacute;is que no es de tipo A2, sin&amp;oacute; de un tipo &lt;em&gt;raro&lt;/em&gt;: el proxy que crea Unity para poder interceptar los m&amp;eacute;todos virtuales (comparad el wach para a2 y a2newed:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/image_5F00_6CD319CE.png"&gt;&lt;img height="53" width="244" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/image_5F00_thumb_5F00_691160FF.png" alt="image" border="0" title="image" style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Implementando el c&amp;oacute;digo en nuestro Handler&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Vamos a modificar el m&amp;eacute;todo Invoke de AutoNotifyPropertyHandler para que lance el evento cada vez que se llame a un set de una propiedad&amp;hellip; La clase completa queda tal y como sigue: B&amp;aacute;sicamente en el m&amp;eacute;todo Invoke, miramos si el nombre del m&amp;eacute;todo que se ha llamado empieza por &amp;ldquo;set_&amp;rdquo;, y si es el caso asumimos que es el Setter de una propiedad. Recogemos el valor &lt;em&gt;actual&lt;/em&gt; de la propiedad usando reflection y si no son el mismo, lanzamos el evento &lt;em&gt;PropertyChanged&lt;/em&gt; usando reflection. Y listos! :)&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;class&lt;/span&gt; AutoPropertyChangedHandler : ICallHandler&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; raiseEvt = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; propName = &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;br /&gt;        INotifyPropertyChanged inpc = input.Target &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; INotifyPropertyChanged;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (inpc != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color:#008000;"&gt;// Si el nombre del m&amp;eacute;todo empieza por &amp;quot;set_&amp;quot; es un Setter de propiedad&lt;/span&gt;&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (input.MethodBase.Name.StartsWith(&lt;span style="color:#006080;"&gt;&amp;quot;set_&amp;quot;&lt;/span&gt;))&lt;br /&gt;            {&lt;br /&gt;                propName = input.MethodBase.Name.Substring(4);&lt;br /&gt;                MethodInfo getter = input.Target.GetType().GetProperty(propName).GetGetMethod();&lt;br /&gt;                &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; oldValue = getter.Invoke(input.Target, &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;);&lt;br /&gt;                &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; newValue = input.Arguments[0];&lt;br /&gt;                &lt;span style="color:#008000;"&gt;// Si los valores de newValue y oldValue son distintos&lt;/span&gt;&lt;br /&gt;                &lt;span style="color:#008000;"&gt;// debemos lanzar el evento (la comparaci&amp;oacute;n la hacemos por&lt;/span&gt;&lt;br /&gt;                &lt;span style="color:#008000;"&gt;// Equals si es posible).&lt;/span&gt;&lt;br /&gt;                raiseEvt = newValue == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt; ?&lt;br /&gt;                    newValue != oldValue :&lt;br /&gt;                    !newValue.Equals(oldValue);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        IMethodReturn msg = getNext()(input, getNext);&lt;br /&gt;        &lt;span style="color:#008000;"&gt;// Si el setter no produce excepci&amp;oacute;n, lanzamos el evento&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (raiseEvt &amp;amp;&amp;amp; msg.Exception == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;            RaiseEvent(inpc, propName);&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; msg;&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;int&lt;/span&gt; Order { get; set; }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;// M&amp;eacute;todo que lanza el evento PropertyChanged usando reflection&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; RaiseEvent(INotifyPropertyChanged inpc, &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; propertyName)&lt;br /&gt;    {&lt;br /&gt;        Type type = inpc.GetType();&lt;br /&gt;        FieldInfo evt = &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;br /&gt;        &lt;span style="color:#008000;"&gt;// Buscamos el evento (no estar&amp;aacute; en el propio Type ya que el propio Type&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#008000;"&gt;// ser&amp;aacute; un proxy, pero iteraremos por los tipos base hasta encontrarlo)&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;do&lt;/span&gt;&lt;br /&gt;        {&lt;br /&gt;            evt = type.GetField(&lt;span style="color:#006080;"&gt;&amp;quot;PropertyChanged&amp;quot;&lt;/span&gt;, BindingFlags.Instance | BindingFlags.NonPublic);&lt;br /&gt;            type = type.BaseType;&lt;br /&gt;        } &lt;span style="color:#0000ff;"&gt;while&lt;/span&gt; (evt == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt; &amp;amp;&amp;amp; type.BaseType != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;);&lt;br /&gt;        &lt;span style="color:#008000;"&gt;// Invocamos el evento&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (evt != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;        {&lt;br /&gt;            MulticastDelegate mcevt = evt.GetValue(inpc) &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; MulticastDelegate;&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (mcevt != &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;            {&lt;br /&gt;                mcevt.DynamicInvoke(inpc, &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; PropertyChangedEventArgs(propertyName));&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;p&gt;Ahora podemos comprobar como se lanza el evento autom&amp;aacute;ticamente al modificar una propiedad de A2.&lt;/p&gt;
&lt;p&gt;Un saludo!!!! &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;PD: &lt;/strong&gt;Dije en el post introductorio que no pondr&amp;iacute;a c&amp;oacute;digo, pero finalmente os incluyo el &lt;a target="_blank" href="http://cid-6521c259e9b1bec6.skydrive.live.com/self.aspx/BurbujasNet/ZipsPosts/AutoNotifPropertiesPost1.zip"&gt;zip con el c&amp;oacute;digo de este post&lt;/a&gt; (en SkyDrive).&lt;/p&gt;
&lt;p&gt;PD2: Echad un post a &lt;em&gt;&lt;a target="_blank" href="http://shecht.wordpress.com/2009/12/12/inotifypropertychanged-with-unity-interception-aop/"&gt;INotifyPropertyChanged with Unity Interception AOP&lt;/a&gt;&lt;/em&gt; del blog de Dmitry Shechtman que me ha servido de inspiraci&amp;oacute;n para el ejemplo (yo ten&amp;iacute;a pensado uno mucho m&amp;aacute;s tonto en este primer post).&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=164919" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/etomas/archive/tags/patrones/default.aspx">patrones</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/IoC/default.aspx">IoC</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/unity/default.aspx">unity</category></item><item><title>Objetos que notifican sus cambios de propiedades (0/3): Introducción</title><link>http://geeks.ms/blogs/etomas/archive/2010/01/12/objetos-que-notifican-sus-cambios-de-propiedades-0-3-introducci-243-n.aspx</link><pubDate>Tue, 12 Jan 2010 12:01:08 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:164837</guid><dc:creator>Eduard Tomàs i Avellana</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/etomas/rsscomments.aspx?PostID=164837</wfw:commentRss><comments>http://geeks.ms/blogs/etomas/archive/2010/01/12/objetos-que-notifican-sus-cambios-de-propiedades-0-3-introducci-243-n.aspx#comments</comments><description>&lt;p&gt;Hola a todos!!! Como ha ido la despedida del 2009 y la bienvenida del 2010!!! Espero que os hayáis portado bien y que los reyes os hayan traído muuuuchos regalitos!&lt;/p&gt;  &lt;p&gt;En este post quiero dejar de lado la serie que estaba haciendo sobre facebook connect, para ver como, gracias a Unity, podemos crear objetos que nos notifiquen cuando cambian sus propiedades, sin que nosotros debamos añadir (casi) ningún código adicional!&lt;/p&gt;  &lt;p&gt;Pienso que es un muy buen ejemplo del poder de usar un contenedor IoC, además de resolver una situación que se da muchas veces: quiero enterarme de los cambios sobre las propiedades de un objeto, pero no quiero codificar dicho objeto de ninguna forma especial (es decir, no poner ningún tipo de código a la clase de cuyos cambios de propiedad deseo enterarme).&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Donde queremos llegar…&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Cuando hablamos de contenedores IoC, nos vienen a la cabeza dos grandes patrones: Dependency Injection y Service Locator… pero hay otra poderosísima razón para usarlos: las &lt;em&gt;intercepciones&lt;/em&gt;. Esta capacidad permite “enchufar” código a los objetos en tiempo de ejecución, lo que permite añadir capacidades de &lt;a href="http://en.wikipedia.org/wiki/Aspect-oriented_programming" target="_blank"&gt;AOP&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;En este caso vamos a configurar la intercepción de Unity, para enchufar código cada vez que se lea/modifique una propiedad de un objeto. Dicho código nos notificará la lectura o escritura de la propiedad.&lt;/p&gt;  &lt;p&gt;Además vamos a hacerlo configurable, de forma que no recibamos notificaciones de todas las propiedades, sino sólo de aquellas que nos interesen! La configuración de què propiedades queremos recibir notificación vamos a tenerla en &lt;em&gt;otra&lt;/em&gt; clase. El objetivo es llegar a un código como el que sigue:&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;[PropertyNotifier(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(UfoNotifications))]&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Ufo&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;virtual&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; Name { get; set; }&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;virtual&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; Edad { get; set; }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&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; UfoNotifications : PropertyNotifications&amp;lt;Ufo&amp;gt;&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; UfoNotifications()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.OnProperty(x =&amp;gt; x.Name).Set.Notify.WithParameters();&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.OnProperty(x =&amp;gt; x.Name).Get.Notify.WithoutParameters();&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.OnProperty(x =&amp;gt; x.Edad).Get.Notify.WithoutParameters();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;El primer código nos define una clase Ufo. Es una clase totalmente normal, salvo por dos detalles:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;El atributo PropertyNotifier nos indica que queremos recibir notificaciones cuando se lean/modifiquen propiedades de dicha clase, y indica que la configuración sobre cuales son las propiedades que deseamos notificar se encuentra en la clase &lt;em&gt;UfoNotifications&lt;/em&gt; &lt;/li&gt;

  &lt;li&gt;Todas las propiedades son virtuales. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;El segundo código contiene la configuración sobre qué propiedades y qué notificaciones queremos recibir. En este caso usamos una aproximación tipo &lt;a href="http://en.wikipedia.org/wiki/Fluent_interface" target="_blank"&gt;&lt;em&gt;fluent interface&lt;/em&gt;&lt;/a&gt;&lt;em&gt;&amp;#160;&lt;/em&gt;cuya ventaja principal es que el código es mucho más fácil de leer (y de escribir).&lt;/p&gt;

&lt;p&gt;Esta serie va a constar de tres posts que publicaré en breve (a medida que publique los posts iré modificando éste para añadir los enlaces):&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;a href="http://geeks.ms/blogs/etomas/archive/2010/01/13/objetos-que-notifican-sus-cambios-de-propiedades-1-3-la-intercepci-243-n.aspx" target="_blank"&gt;Como configurar el mecanismo de intercepción de Unity para enchufar nuestro código&lt;/a&gt; &lt;strong&gt;(Añadido el 13/01/2009)&lt;/strong&gt;. &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://geeks.ms/blogs/etomas/archive/2010/01/14/objetos-que-notifican-sus-cambios-de-propiedades-2-3-publish-and-subscribe.aspx" target="_blank"&gt;Como podemos notificar los cambios de propiedades, sin obligar a que quien quiera recibirlos tenga que tener una referencia al objeto que los notifica&lt;/a&gt; (lo que nos impide usar eventos tradicionales de .NET) &lt;strong&gt;(Añadido el 14/01/2009)&lt;/strong&gt;.&lt;/li&gt;

  &lt;li&gt;Como crear la &lt;em&gt;fluent interface&lt;/em&gt;&amp;#160; para configurar las notificacioes &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strike&gt;No voy a adjuntar código en cada post porque sólo tengo la solución completa implementada… en el último post adjuntaré &lt;strong&gt;todo&lt;/strong&gt; el código, junto con un ejemplo.&lt;/strike&gt; Al final sí que adjunto un zip en cada post :)&lt;/p&gt;

&lt;p&gt;Nos leemos!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=164837" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/etomas/archive/tags/patrones/default.aspx">patrones</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/IoC/default.aspx">IoC</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/unity/default.aspx">unity</category></item><item><title>Evita las dependencias con tu contendor de IoC</title><link>http://geeks.ms/blogs/etomas/archive/2009/12/01/evita-las-dependencias-con-tu-contendor-de-ioc.aspx</link><pubDate>Tue, 01 Dec 2009 15:16:21 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:161672</guid><dc:creator>Eduard Tomàs i Avellana</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/etomas/rsscomments.aspx?PostID=161672</wfw:commentRss><comments>http://geeks.ms/blogs/etomas/archive/2009/12/01/evita-las-dependencias-con-tu-contendor-de-ioc.aspx#comments</comments><description>&lt;p&gt;Usar un contenedor de IoC es una práctica más que recomendable, pero al hacerlo es muy fácil caer en el anti-patrón de &lt;em&gt;dependencia con el contenedor&lt;/em&gt;. Ese patrón se manifesta de varias formas sútiles, y aunque hay algunos casos en que pueda ser aceptable, en la gran mayoría indica una mala práctica que debemos revisar.&lt;/p&gt;  &lt;p&gt;¿Que tiene de malo este 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:#008000;"&gt;// IS1 y IS2 son dos interfaces cualesquiera&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#008000;"&gt;// S1 y S2 son dos clases que implementan dichas interfaces&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; A&lt;br /&gt;{&lt;br /&gt;    IS1 s1;&lt;br /&gt;    IS2 s2;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; A(IUnityContainer container)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.s1 = container.Resolve&amp;lt;IS1&amp;gt;();&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.s2 = container.Resolve&amp;lt;IS2&amp;gt;();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Program&lt;br /&gt;{&lt;br /&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;        IUnityContainer ctr = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; UnityContainer();&lt;br /&gt;        ctr.RegisterType&amp;lt;IS1, S1&amp;gt;();&lt;br /&gt;        ctr.RegisterType&amp;lt;IS2, S2&amp;gt;();&lt;br /&gt;        A a = ctr.Resolve&amp;lt;A&amp;gt;();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;El código funciona correctamente, pero ¡ojo! Tenemos una dependencia directa de la clase A hacia &lt;em&gt;IUnityContainer&lt;/em&gt;. &lt;em&gt;Realmente&lt;/em&gt; la clase A depende de IUnityContainer o bien depende de IS1 y IS2? La realidad es que las dependencias de la clase A son IS1 e IS2.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. La visión filosófica del asunto&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Si yo leo el constructor de la clase A y veo que pone:&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; A(IUnityContainer container)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#008000;"&gt;// Código...&lt;/span&gt;&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Debo leer &lt;em&gt;todo&lt;/em&gt; el código del constructor para ver las dependencias &lt;em&gt;reales&lt;/em&gt; de la clase A. Por otro lado si el constructor fuese:&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; A(IS1 s1, IS2 s2)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#008000;"&gt;// Código&lt;/span&gt;&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Ahora queda mucho más claro que las dependencias &lt;em&gt;reales&lt;/em&gt; de la clase A son IS1 y IS2. &lt;/p&gt;

&lt;p&gt;En resumen: &lt;strong&gt;evitad &lt;/strong&gt;en lo máximo de lo posible pasar el propio contenedor como parámetro de los constructores. En su lugar pasad las dependencias reales y dejad que el contenedor las inyecte.&lt;/p&gt;

&lt;p&gt;Y obviamente &lt;strong&gt;evitad (casi) siempre&lt;/strong&gt; un código como:&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;class&lt;/span&gt; A&lt;br /&gt;{&lt;br /&gt;    IUnityContainer container;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; A(IUnityContainer container)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.container = container;&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color:#008000;"&gt;// Código&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;¡Ahí estamos todavía más vendidos! Para averiguar las dependencias reales de la clase A, ahora debemos mirar &lt;em&gt;todo el código&lt;/em&gt; de la clase A, puesto que en cualquier sitio alguien puede hacer un &lt;em&gt;resolve &lt;/em&gt;(antes de que alguien salte por las paredes que eche un vistazo al punto 4 del post, por favor :p).&lt;/p&gt;

&lt;p&gt;La visión “filosófica” me indica que si la clase A debería depender solo de IS1 e IS2 no es posible que me aparezca una dependencia sobre IUnityContainer. Necesita la clase A a IUnityContainer para hacer su trabajo? No, verdad? Pues eso.&lt;/p&gt;

&lt;p&gt;Incluso aunque tengas claro, clarísimo que nunca vas a abandonar Unity (él no lo haría! :p) este código &lt;em&gt;no huele nada bien&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. La visión práctica&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Algún dia quizá te canses e Unity y te decidas a usar por ejemplo, Windsor Container… Este cambio debería ser un cambio sencillo: un cambio en el bootstrapper de tu aplicación, y donde instanciabas Unity ahora instancias Windsor, lo configuras y listo!&lt;/p&gt;

&lt;p&gt;Listo? Listo sólo si tus clases &lt;strong&gt;no&lt;/strong&gt; dependen de IUnityContainer, porque en caso contrario… bueno, puedes tener un buen problemilla ;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Algunos detalles...&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Antes he comentado que este anti-patrón puede aparecer de formas realmente sutiles:&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;class&lt;/span&gt; A&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; A() &lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#008000;"&gt;//...&lt;/span&gt;&lt;br /&gt;    }&lt;br /&gt;    [Dependency()]&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; IS1 S1 { get; set; }&lt;br /&gt;    &lt;span style="color:#008000;"&gt;// Más código&lt;/span&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;¿Es correcto este código? Mejor que el código anterior donde recibíamos IUnityContainer como parámetro si que es, porque no tenemos ninguna dependencia directa contra Unity… Pero realmente &lt;em&gt;si&lt;/em&gt; que estamos dependiendo de Unity: Sólo Unity entenderá el atributo [Dependency()] para inyectarnos la propiedad S1. Así que a la práctica estamos como en el caso anterior.&lt;/p&gt;

&lt;p&gt;Ahora bien, la diferencia fundamental es que, en mi opinión, que la clase A reciba IUnityContainer como parámetro rebela un mal diseño, mientras que en este caso la dependencia nos aparece porque &lt;strong&gt;no&lt;/strong&gt; existe ningún mecanismo estándar para especificar que queremos que una propiedad sea inyectada (por lo que cada contenedor usa su propio mecanismo).&lt;/p&gt;

&lt;p&gt;Si tienes claro, clarísimo que nunca abandonarás Unity, entonces &lt;strong&gt;no&lt;/strong&gt; hay problema alguno en este código. Por otro lado si no quieres atarte al contenedor entonces este código no te sirve (echa un vistazo a mi post &lt;a href="http://geeks.ms/blogs/etomas/archive/2009/02/02/unity-s-237-gracias-pero-no-me-abraces-demasiado.aspx"&gt;Unity? Sí gracias, pero no me abraces demasiado&lt;/a&gt; para ver más detalles al respecto).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Ya, pero yo uso el patrón Service Locator&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Todo lo que hemos hablado hasta ahora afecta sobre todo en aquellos casos en que usábamos inyección de dependencias, pero existe otro patrón íntimamente relacionado: el &lt;em&gt;service locator&lt;/em&gt;. En este patrón tenemos un objeto (el propio &lt;em&gt;service locator&lt;/em&gt;) que se encarga de devolvernos referencias a servicios.&lt;/p&gt;

&lt;p&gt;Es común que el propio contenedor de IoC se use como service locator, porque ofrece soporte directo para ello. Sin embargo &lt;strong&gt;no es una buena opción&lt;/strong&gt;… porque conduce inevitablemente a situaciones como las que hemos visto, en concreto a situaciones como esta:&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;class&lt;/span&gt; A&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; IUnityContainer serviceLocator;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; A(IUnityContainer serviceLocator) &lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.serviceLocator = serviceLocator;&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; foo()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#008000;"&gt;// obtengo los servicios...&lt;/span&gt;&lt;br /&gt;        var logSvc = serviceLocator.Resolve&amp;lt;ILogService&amp;gt;();&lt;br /&gt;        var locSvc = serviceLocator.Resolve&amp;lt;ILocalizationService&amp;gt;();&lt;br /&gt;        &lt;span style="color:#008000;"&gt;// hago cosas con mis servicios&lt;/span&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Este código es prácticamente igual al que os decía que debéis evitar a toda costa. Podríamos pasar ILogService e ILocalizationService en el constructor, pero ahora imaginad que tenemos muchos servicios y nuestras clases los usan todos (en un proyecto en el que estoy trabajando manejamos decenas de servicios, y además es común que las clases usen muchos de los servicios sólo en un método).&lt;/p&gt;

&lt;p&gt;El error aquí, está en usar &lt;em&gt;el propio contenedor&lt;/em&gt; como Service Locator: lo hacemos porque es rápido y cómodo ya que el contenedor nos ofrece soporte para ello, pero a cambio nos estamos atando al contenedor… Nosotros no queremos una dependencia contra IUnityContainer, sinó una dependencia contra el &lt;em&gt;service locator&lt;/em&gt;. Y qué es el service locator? Pues &lt;em&gt;algo distinto&lt;/em&gt; al propio contenedor. Por ejemplo, eso:&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;interface&lt;/span&gt; IServiceLocator&lt;br /&gt;{&lt;br /&gt;    T GetService&amp;lt;T&amp;gt;() &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; T : &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; ServiceLocator : IServiceLocator&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; IUnityContainer container;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; ServiceLocator(IUnityContainer container)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.container = container;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; T GetService&amp;lt;T&amp;gt;() &lt;span style="color:#0000ff;"&gt;where&lt;/span&gt; T : &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt;&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.container.Resolve&amp;lt;T&amp;gt;();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;La clase ServiceLocator si que depende de Unity (ahí si que es inevitable la dependencia). Ahora la clase A la podemos reescribir como:&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;class&lt;/span&gt; A&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; IServiceLocator serviceLocator;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; A(IServiceLocator serviceLocator) &lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.serviceLocator = serviceLocator;&lt;br /&gt;    }&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; foo()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#008000;"&gt;// obtengo los servicios...&lt;/span&gt;&lt;br /&gt;        var logSvc = serviceLocator.GetService&amp;lt;ILogService&amp;gt;();&lt;br /&gt;        var locSvc = serviceLocator.GetService&amp;lt;ILocalizationService&amp;gt;();&lt;br /&gt;        &lt;span style="color:#008000;"&gt;// hago cosas con mis servicios&lt;/span&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;
  &lt;p&gt;Y la clase A ya no depende de IUnityContainer: lo hace de IServiceLocator, lo que es aceptable y totalmente lógico.&lt;/p&gt;

  &lt;p&gt;Además, tener nuestra propia implementación del &lt;em&gt;service locator&lt;/em&gt; nos permite adaptarlo a nuestras necesidades (p. ej. ¿qué hacer si nos piden un servicio que no está registrado?).&lt;/p&gt;

  &lt;p&gt;Así pues, usar el patrón &lt;em&gt;service locator&lt;/em&gt; no es excusa para tener nuestro código lleno de dependencias contra el contenedor de IoC.&lt;/p&gt;

  &lt;p&gt;¿Opiniones? ;-)&lt;/p&gt;

  &lt;p&gt;Un saludo a todos!&lt;/p&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=161672" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/etomas/archive/tags/patrones/default.aspx">patrones</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/IoC/default.aspx">IoC</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/unity/default.aspx">unity</category></item><item><title>¿MVP e IoC trabajando juntos? ¡Pues claro!</title><link>http://geeks.ms/blogs/etomas/archive/2009/10/13/191-mvp-e-ioc-trabajando-juntos-161-pues-claro.aspx</link><pubDate>Tue, 13 Oct 2009 10:09:01 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:157928</guid><dc:creator>Eduard Tomàs i Avellana</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/etomas/rsscomments.aspx?PostID=157928</wfw:commentRss><comments>http://geeks.ms/blogs/etomas/archive/2009/10/13/191-mvp-e-ioc-trabajando-juntos-161-pues-claro.aspx#comments</comments><description>&lt;p&gt;Un comentario de Galcet en mi post “&lt;a href="http://geeks.ms/blogs/etomas/archive/2009/09/17/como-independizar-tu-capa-de-l-243-gica-de-tu-capa-de-presentaci-243-n.aspx"&gt;Como independizar tu capa lógica de tu capa de presentación&lt;/a&gt;” decía que el entendía por separado los conceptos de IoC y los de MVC pero que no veía como podían trabajar juntos… El motivo de este post es para comentar precisamente esto: no sólo cómo MVC e IoC pueden trabajar juntos sinó las ventajas que la combinación de ambos patrones nos aporta.&lt;/p&gt;  &lt;p&gt;Galcet no comentaba si se refería a aplicaciones desktop o web. En este post voy a tratar aplicaciones de escritorio (por lo que me centraré en el patrón MVP más que en el MVC dado que, en mi opinión, MVP aplica mejor que MVC en aplicaciones desktop). En aplicaciones web, si usamos ASP.NET MVC el tema se simplifica mucho, dado que ASP.NET MVC está “preparado” para que sea muy fácil crear nuestros controladores mediante cualquier contenedor IoC.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;La filosofía CAB + SCSF&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;CAB (o &lt;a href="http://msdn.microsoft.com/en-us/library/aa480450.aspx"&gt;Composite UI Application Block&lt;/a&gt;) es un framework para el desarrollo de aplicaciones de escritorio winforms con interfaz de usuario compleja. Se basa en el patrón MVP y se compone de varios assemblies y una guía de buenas prácticas. Aunque puede usarse sola, suele combinarse con SCSF (&lt;a href="http://msdn.microsoft.com/en-us/library/aa480482.aspx"&gt;Smart Client Software Factory&lt;/a&gt;), un conjunto de guías, librerías y buenas prácticas para la creación de aplicaciones winforms complejas. La recomendación de SCSF para la interfaz de usuario es usar CAB, y de hecho &lt;em&gt;extiende&lt;/em&gt; CAB. No voy a hablar aquí ni de CAB ni de SCSF (hay varios tutoriales en internet), sino de como CAB y SCSF afrontan el uso de IoC junto con MVP.&lt;/p&gt;  &lt;p&gt;La filosofía de SCSF es que nosotros creamos las vistas y las vistas crean a su presenter asociado. El código equivalente usando Unity sería algo parecido 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;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; View : UserControl, IView&lt;br /&gt;{    &lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; View ()    &lt;br /&gt;    {        &lt;br /&gt;        InitializeComponents();        &lt;br /&gt;        &lt;span style="color:#008000;"&gt;// Resto de código...    &lt;/span&gt;&lt;br /&gt;    }    &lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; IMyPresenter _presenter;&lt;br /&gt;    [Dependency()]&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; IMyPresenter Presenter&lt;br /&gt;    {&lt;br /&gt;        get { &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; _presenter;}&lt;br /&gt;        set&lt;br /&gt;        {&lt;br /&gt;            _presenter = &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;;&lt;br /&gt;            _presenter.View = &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;;&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;class&lt;/span&gt; MyPresenter : IPresenter&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; IView View { get; set;}    &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;El contenedor debe tener registrado el mapping entre las interfaces y las clases:&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;container.RegisterType&amp;lt;IPresenter, MyPresenter&amp;gt;();&lt;br /&gt;&lt;br /&gt;container.RegisterType&amp;lt;IView, View&amp;gt;();&lt;br /&gt;&lt;span style="color:#008000;"&gt;// Creamos la vista&lt;/span&gt;&lt;br /&gt;var view = container.Resolve&amp;lt;IView&amp;gt;();&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Al llamar al método Resolve, Unity consulta sus mappings y llega a la conclusión de que debe crear un objeto View. La clase View tiene una propiedad “Presenter” decorada con [Dependency()], por lo que Unity debe inyectar un valor a esta propiedad. La propiedad es de tipo IMyPresenter, Unity consulta sus mappings y vee que debe crear un objeto de la clase MyPresenter. Luego en el setter de la propiedad “Presenter” la vista se asigna a si misma como vista del presenter recién creado.&lt;/p&gt;

&lt;p&gt;A lo mejor alguien se pregunta porque no usamos inyección de dependencias en el constructor del presenter, es decir que en lugar de que nuestro presenter declare una propiedad que reciba la vista y rellenar esta propiedad desde la propia vista, declaramos la vista en el constructor y que Unity se encargue de todo:&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; View : UserControl, IView&lt;br /&gt;{        &lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; View ()        &lt;br /&gt;    {                &lt;br /&gt;        InitializeComponents();                &lt;br /&gt;        &lt;span style="color:#008000;"&gt;// Resto de código...        &lt;/span&gt;&lt;br /&gt;    }        &lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; IMyPresenter _presenter;    &lt;br /&gt;    [Dependency()]    &lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; IMyPresenter Presenter { get; set;}&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; MyPresenter : IPresenter&lt;br /&gt;{    &lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; MyPresenter (IView view)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#008000;"&gt;// Nos guardamos la vista...&lt;/span&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;¿Qué problema hay en este código? A priori puede parecer que ninguno, pero si repasamos como actuaría Unity:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Al llamar a Resolve&amp;lt;IView&amp;gt; Unity consulta sus mappings y ve que debe crear un objeto de la clase View&lt;/li&gt;

  &lt;li&gt;Al inyectar la propiedad Presenter, Unity consulta sus mappings y ve que debe crear un objeto de la clase MyPresenter&lt;/li&gt;

  &lt;li&gt;Al intentar crear un objeto MyPresenter, Unity observa que el constructor recibe un IView y que debe inyectarlo.&lt;/li&gt;

  &lt;li&gt;Así pues, Unity consulta sus mappings y &lt;strong&gt;crea un nuevo&lt;/strong&gt; objeto View que inyectará en el constructor del MyPresenter.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Suponiendo que todo esto no terminase en un Stack Overflow, en todo caso el objeto MyPresenter recibiría un objeto View distinto del que devolvería la llamada a Resolve.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;El “problema” de Visual Studio&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;¿Porque ha optado CAB por esta filosofía? ¿Porque las vistas crean a los presenters y no al revés? ¿Porque la inyección de dependencias es por propiedades y no en el constructor? La respuesta a todos estos interrogantes se llama Visual Studio.&lt;/p&gt;

&lt;p&gt;Me explico: si tenemos una vista (o sea un UserControl) llamada View, cuando la arrastramos dentro de un formulario, o de un panel Visual Studio genera un código parecido 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;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;View view1 = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; View();&lt;br /&gt;panel1.Controls.Add(view1);&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;¿Observáis el problema? Visual Studio ha creado una instancia de la vista, usando new, no usando el método Resolve del contenedor de IoC, por lo tanto nos podemos olvidar de la inyección de dependencias, por lo que efectivamente nuestro presenter no estará creado.&lt;/p&gt;

&lt;p&gt;¿Como podemos solucionar este problema? Bueno… todos los controladores IoC permiten “inicializar” un objeto ya creado, entendiendo por “inicializar” inyectar todas las dependencias que este objeto necesita (en el caso de nuestras vistas, la propiedad “Presenter”). En el caso de Unity este método se llama BuildUp, y se le pasa la instancia del objeto a inicializar. Lo que debemos hacer es inicializar todos los controles que estén en el formulario, lo que podemos hacer en el método Main:&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;[STAThread]&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Main()&lt;br /&gt;{&lt;br /&gt;    Application.EnableVisualStyles();&lt;br /&gt;    Application.SetCompatibleTextRenderingDefault(&lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;);&lt;br /&gt;    Form1 frm = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Form1();&lt;br /&gt;    IUnityContainer container = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; UnityContainer();&lt;br /&gt;    frm.BuildUpControls(container);&lt;br /&gt;    Application.Run(frm);&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Donde el método “BuildUpControls” es un método de extensión definido de la siguiente manera:&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;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; FormExtensions&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; BuildUpControls (&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt; Control self,&lt;br /&gt;        IUnityContainer container)&lt;br /&gt;    {&lt;br /&gt;        container.BuildUp(self);&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (Control control &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; self.Controls)&lt;br /&gt;        {&lt;br /&gt;            control.BuildUpControls(container);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;El método BuildUpControls va recorriendo recursivamente la colección “Controls” para llamar al método “BuildUp” del contenedor con todos los controles creados. En este caso no miramos nada más, por lo que inicializamos todos los controles (incluso las labels, los textboxes…), lo que es excesivo. Un refinamiento es inicializar sólo aquellos controles que sean “vistas”. Por ejemplo, CAB para saber que un control es una “vista” y que debe ser inicializado obliga a decorarlo con el atributo [SmartPart]. &lt;/p&gt;

&lt;p&gt;Evidentemente si nosotros mismos añadimos en run-time una vista debemos inicializarla “manualmente”:&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;Subview view = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Subview();&lt;br /&gt;view.BuildUpControls(container);&lt;br /&gt;&lt;span style="color:#008000;"&gt;// O bien...&lt;/span&gt;&lt;br /&gt;Subview view = container.Resolve&amp;lt;Subview&amp;gt;();&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Eso mismo ocurre en CAB: si en CAB creamos una vista de forma programática también debemos “inicializarla”. CAB gestiona la inicialización de una forma totalmente distinta, pero la &lt;em&gt;filosofía&lt;/em&gt; es la misma (que es lo que intento contar).&lt;/p&gt;

&lt;p&gt;Pues bueno… hemos visto como podemos combinar el uso de un contenedor IoC (como siempre en mi caso Unity :p) junto con el patrón MVP. Fijaos que los presenters si que están creados por Unity, por lo que pueden recibir dependencias inyectadas en el constructor (p.ej. a un servicio de log).&lt;/p&gt;

&lt;p&gt;Un saludo!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=157928" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/etomas/archive/tags/patrones/default.aspx">patrones</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/IoC/default.aspx">IoC</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/unity/default.aspx">unity</category></item><item><title>IoC o el poder de ceder el control (ii): Dependency Injection</title><link>http://geeks.ms/blogs/etomas/archive/2009/10/08/ioc-o-el-poder-de-ceder-el-control-ii-dependency-injection.aspx</link><pubDate>Thu, 08 Oct 2009 10:11:04 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:157619</guid><dc:creator>Eduard Tomàs i Avellana</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/etomas/rsscomments.aspx?PostID=157619</wfw:commentRss><comments>http://geeks.ms/blogs/etomas/archive/2009/10/08/ioc-o-el-poder-de-ceder-el-control-ii-dependency-injection.aspx#comments</comments><description>&lt;p&gt;Hace ya algún tiempecillo publiqué por aquí un post sobre &lt;a href="http://es.wikipedia.org/wiki/Inversi%C3%B3n_de_Control"&gt;IoC&lt;/a&gt;, titulado &lt;a href="http://geeks.ms/blogs/etomas/archive/2008/10/28/ioc-o-el-poder-de-ceder-el-control.aspx"&gt;IoC o el poder de ceder el control&lt;/a&gt;. En el post mencionaba dos de los patrones clásicos asociados con IoC, el &lt;em&gt;service locator&lt;/em&gt; y la inyección de dependencias (&lt;em&gt;dependency injection&lt;/em&gt;), pero luego sólo me centraba en Service Locator. Un par de comentarios en dicho post decían si era posible algo similar pero explicando la inyección de dependencias, así que a ello vamos ;-)&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Dependencias de una clase&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Para entender como funciona la inyección de dependencias tenemos que tener claro que entendemos por dependencias de una clase: Básicamente una clase tiene dependencias con todas las otras clase que &lt;em&gt;utilice&lt;/em&gt;, ya sea reciba objetos de dicha clase como parámetros, los devuelva como valores de retorno o cree variables locales o de clase.&lt;/p&gt;  &lt;p&gt;Las dependencias no son nada malo y de hecho no son evitables: es evidente que las clases cooperan unas con otras para realizar alguna acción conjunta, así que es lógico que nuestro código depende de otras clases. Lo que debe preocuparnos es el &lt;em&gt;acoplamiento&lt;/em&gt; de nuestro código con estas dependencias, o dicho de otro modo: cuanto nos costaría cambiar &lt;em&gt;nuestra&lt;/em&gt; clase para que en lugar de depender de una clase X, dependiese de &lt;em&gt;otra&lt;/em&gt; clase Y que ofrece la misma funcionalidad. Si has de modificar muchas líneas de código es que tienes un alto acoplamiento (y eso sí que es malo). El objetivo de la inyección de dependencias es facilitarte conseguir un acoplamiento lo más bajo posible.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Alto acoplamiento: uso directo de clases&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;El nivel de acoplamiento mayor es cuando nuestros métodos trabajan con parámetros cuyo tipo es una clase:&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; X&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; MyLogClass Logger { get; &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; set;}&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; X (MyLogClass logger)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Logger = logger;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;La clase X tiene un alto acoplamiento con la clase MyLogClass. Si quisiéramos cambiar MyLogClass por otra clase distinta, llamésmole MyLogClass2 que tenga la misma funcionalidad deberemos modificar la clase X para que la propiedad Logger sea de tipo MyLogClass, asi como modificar el constructor… Parece sencillo, pero tened en cuenta que nuestra clase X será llamada por varias clases distintas. Todas las clases que crean un objeto de X, crearán un objeto MyLogClass para pasarlo como parámetro al constructor: deberemos cambiar también todas estas clases.&lt;/p&gt;

&lt;p&gt;Un cambio que debería ser fácil y que debería afectar sólo a una clase, se convierte, por culpa de alto acoplamiento, en un cambio complejo, que afecta a multitud de clases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Acoplamiento medio: Interfaces&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Las interfaces ayudan solucionar el problema. Podemos definir la clase X para que trabaje con interfaces:&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; X&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; ILogger Logger { get; &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; set;}&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; X (ILogger logger)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Logger = logger;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Ahora la clase X no tiene dependencia alguna con MyLogClass. Podemos utilizar MyLogClass, MyLogClass2 o cualquier clase que implemente ILogger.&lt;/p&gt;

&lt;p&gt;Pero el problema no está resuelto al 100%. Para crear objetos de la clase X, debemos pasarle en el constructor un objeto &lt;em&gt;de una clase&lt;/em&gt; que implemente ILogger:&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;MyLogClass logger = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; MyLogClass();&lt;br /&gt;X x = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; X(logger);&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Es decir la clase X no depende de MyLogClass, pero todas aquellas clases que crean objetos de la clase X sí, ya que deben crear un MyLogClass para pasarlo como parámetro al constructor. De nuevo modificar MyLogClass por MyLogClass2 implica localizar todos aquellos sitios donde se crean objetos de X y modificarlo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Acoplamiento bajo: Interfaces + Factoría&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Llegados a este punto alguien puede tener la idea “&lt;em&gt;hey! porque no creamos una factoria de ILogger, que sea la responsable de crear los objetos?&lt;/em&gt;”. Es una gran idea ya que &lt;em&gt;mueve&lt;/em&gt; todas las dependencias a la clase en UN sólo sitio, la factorí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;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;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; ILoggerFactory&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; ILogger GetLogger()&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; MyLogClass();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#008000;"&gt;// ... Luego en cualquier otro sitio ...&lt;/span&gt;&lt;br /&gt;X x = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; X (ILoggerFactory.GetLogger());&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Ahora si en lugar de querer usar MyLogClass queremos usar MyLogClass2 sólo debemos modificar la factoría.&lt;/p&gt;

&lt;p&gt;Hey! Y todo eso &lt;strong&gt;sin&lt;/strong&gt; usar IoC… entonces para que el post? Bueno… imagina que &lt;em&gt;por cualquier razón&lt;/em&gt;, debes modificar el constructor de X para que acepte algún otro parámetro:&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; X&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; X (ILogger log, IFormatter frm);    &lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Sigue imaginando que, por la razón que sea, no puedes seguir teniendo el constructor con un solo parámetro ILogger, ya que no puedes asignar ningún valor por defecto a IFormatter. Pues bien… en este caso de nuevo debes volver a localizar todas las llamadas al constructor de X y modificarlas para pasar el nuevo parámetro&amp;#160; (que por supuesto sacarás de otra factoría que crearás).&lt;/p&gt;

&lt;p&gt;Por suerte no estamos en un callejón sin salida: la inyección de dependencias viene para solucionar este &lt;em&gt;pequeño&lt;/em&gt; problema.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Acoplamiento muy bajo: Inyección de dependencias&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;La inyección de dependencias se basa en el mismo principio que la factoría: No creas tu los objetos directamente, sinó que delegas esta responsabilidad en alguien. La diferencia respecto a la factoría tradicional, es que este alguien es un contenedor de IoC, capaz de &lt;em&gt;crear&lt;/em&gt; todos aquellos parámetros necesarios e inyectarlos en el constructor. Si añades un parámetro nuevo, apenas deberás hacer nada: el contenedor de IoC &lt;em&gt;automáticamente&lt;/em&gt; sabrá inyectar este nuevo parámetro.&lt;/p&gt;

&lt;p&gt;Vamos a ver un ejemplo usando &lt;a href="http://msdn.microsoft.com/en-us/library/dd203104.aspx"&gt;Unity&lt;/a&gt;, el contenedor IoC de la gente de Patterns &amp;amp; Practices. Primero comento muy rápidamente los conceptos básicos de Unity.&lt;/p&gt;

&lt;p&gt;La gracia está en &lt;em&gt;mapear&lt;/em&gt; un tipo a una interfaz, con esto le decimos al contenedor que cuando pidamos objetos de una interfaz nos devuelva objetos de una clase determinada. Esto en Unity se consigue con el método RegisterType:&lt;/p&gt;

&lt;p&gt;&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;IUnityContainer container = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; UnityContainer();&lt;br /&gt;container.RegisterType&amp;lt;ILogger, MyLogClass&amp;gt;();&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Cuando pidamos un ILogger, Unity nos devolverá un MyLogClass… Y como le pedimos a Unity un ILogger? Pues usando el método Resolve:&lt;/p&gt;

&lt;p&gt;&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;ILogger logger = container.Resolve&amp;lt;ILogger&amp;gt;();&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Hasta aquí todo muy parecido a la factoría. Ahora viene lo bueno: Si tenemos mappings registrados en Unity para las interfaces, Unity puede inyectar estos mappings en cualquier constructor. Es decir:&lt;/p&gt;

&lt;p&gt;&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;container.RegisterType&amp;lt;ILogger, MyLogClass&amp;gt;();&lt;br /&gt;container.RegisterType&amp;lt;IFormatter, MyFormatClass&amp;gt;();&lt;br /&gt;X x = container.Resolve&amp;lt;X&amp;gt;();&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Con las dos primeras líneas hemos configurado nuestro contenedor de IoC para que sepa que devolver cuando se le pida un ILogger y un IFormatter. Con la tercera línea estamos pidiendo un objeto de tipo X. Entonces Unity hace lo siguiente:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Mira si tiene algún mapeo que mapee X a una clase en concreto (en principio Unity no sabe que X es una clase y no una interfaz). &lt;/li&gt;

  &lt;li&gt;Al no tenerlo, deduce que es una clase y que debe crear un objeto de la clase X. Para ello inspecciona la clase X, y ve que el constructor requiere dos parámetros, un ILogger y un IFormatter. 
    &lt;ol&gt;
      &lt;li&gt;Unity resuelve el primer parámetro &lt;/li&gt;

      &lt;li&gt;Unity resuelve el segundo parámetro &lt;/li&gt;

      &lt;li&gt;Unity pasa los valores de los dos parámetros resueltos al constructor de la clase X y devuelve el objeto X creado. Es decir, Unity &lt;strong&gt;inyecta&lt;/strong&gt; los parámetros necesarios en el constructor. &lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Es decir, lo que Unity &lt;em&gt;hace por nosotros&lt;/em&gt; es equivalente a si hubieramos hecho:&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;ILogger p1 = container.Resolve&amp;lt;ILogger&amp;gt;();&lt;br /&gt;IFormatter p2 = container.Resolve&amp;lt;IFormatter&amp;gt;();&lt;br /&gt;X x = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; X(p1, p2);&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Llegados a este punto… si se modificase el constructor de la clase X para hacer aparecer un tercer parámetro… tan sólo debemos hacer &lt;strong&gt;una&lt;/strong&gt; modificación en nuestro código: Donde configuramos el contenedor de Unity, poner una llamada más a RegisterType(), para que Unity sepa que devolver cuando se encuentre un parámetro de dicho tipo. Pero dado que en nuestro códgo siempre obtenemos instancias de X llamando a container.Resolve&amp;lt;X&amp;gt;(), no deberemos modificar &lt;strong&gt;ninguna&lt;/strong&gt; línea más de nuestro código.&lt;/p&gt;

&lt;p&gt;Llegados a este punto, comentaros dos cosillas:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Lo que hemos visto se llama inyección de dependencias en el constructor, y es uno de los mecanismos más normales. Otra forma común de inyectar dependencias es usar propiedades: es decir, el contenedor IoC al crear el objeto, inyecta valores en todas las propiedades que nosotros le indiquemos. &lt;/li&gt;

  &lt;li&gt;Que ocurre en aquellos objetos que por cualquier razón NO pueden ser creados por el contenedor (p.ej. objetos que un framework cree por nostros)? Podemos hacer que estos objetos reciban inyección de dependencias? &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;La respuesta al punto (2) la da el punto (1): Podemos utilizar inyección de dependencias en propiedades y luego, una vez tenemos el objeto ya creado, decirle al contenedor IoC que inyecte las dependencias pendientes. Esto en Unity se hace mediante el método BuildUp, que toma un objeto e inyecta las dependencias pendientes. Por ejemplo imaginad que deserializamos un objeto y queremos que el objeto deserializado reciba dependencias del contenedor de IoC. Es evidente que no podemos poner las dependencias en el constructor (porque no controlamos &lt;em&gt;quien&lt;/em&gt; crea el objeto), pero podemos poner las dependencias en propiedades y una vez tenemos el objeto indicarle al contenedor de IoC que inyecte dichas propiedades. Esto en Unity se consigue mediante el método BuildUp.&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; X&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#008000;"&gt;// Código variado...&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color:#008000;"&gt;// El atributo Dependency indica a Unity que la propiedad debe&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;// ser inyectada&lt;/span&gt;&lt;br /&gt;    [Dependency()]&lt;br /&gt;    [XmlIgnore()]&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; ILogger Logger { get; set;}    &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#008000;"&gt;// En cualquier otro sitio...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;X x = &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;br /&gt;XmlSerializer ser = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; XmlSerializer(&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(X));&lt;br /&gt;x = (X)ser.Deserialize(myStream);&lt;br /&gt;&lt;span style="color:#008000;"&gt;// Inyectamos las propiedades&lt;/span&gt;&lt;br /&gt;container.BuildUp(x);&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Cuando leemos el stream myStream, el propio XmlSerializer nos crea un objeto de la clase X. Luego al llamar al método BuildUp, es cuando el contenedor de IoC inyectará las propiedades.&lt;/p&gt;

&lt;p&gt;Así es como funciona (más o menos :p) la inyección de dependencias.&lt;/p&gt;

&lt;p&gt;Un saludo a todos!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=157619" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/etomas/archive/tags/patrones/default.aspx">patrones</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/IoC/default.aspx">IoC</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/unity/default.aspx">unity</category></item><item><title>Unity, Proxies, AOP y un poco de todo eso…</title><link>http://geeks.ms/blogs/etomas/archive/2009/09/24/unity-proxies-aop-y-un-poco-de-todo-eso.aspx</link><pubDate>Thu, 24 Sep 2009 09:34:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:156639</guid><dc:creator>Eduard Tomàs i Avellana</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/etomas/rsscomments.aspx?PostID=156639</wfw:commentRss><comments>http://geeks.ms/blogs/etomas/archive/2009/09/24/unity-proxies-aop-y-un-poco-de-todo-eso.aspx#comments</comments><description>&lt;p&gt;En mi opini&amp;oacute;n, usar un contenedor de IoC hoy en d&amp;iacute;a, no es una opci&amp;oacute;n sin&amp;oacute; una &lt;em&gt;obligaci&amp;oacute;n&lt;/em&gt;. Las ventajas que nos ofrecen son incotestables. Los patrones &lt;a href="http://msdn.microsoft.com/en-us/library/cc707905.aspx"&gt;Service Locator&lt;/a&gt; y &lt;a href="http://msdn.microsoft.com/en-us/library/dd458879.aspx"&gt;Dependency Injection&lt;/a&gt; nos permiten &lt;em&gt;desacoplar&lt;/em&gt; nuestro c&amp;oacute;digo, y son la base para poder trabajar de forma modular y poder generar unos tests unitarios de forma m&amp;aacute;s sencilla. Pero hoy no quiero hablaros de ninguno de estos patrones, sin&amp;oacute; de otra de las capacidades de los contenedores de IoC: la generaci&amp;oacute;n de proxies.&lt;/p&gt;
&lt;p&gt;Con esta t&amp;eacute;cnica lo que podemos hacer es &lt;em&gt;inyectar&lt;/em&gt; nuestro propio c&amp;oacute;digo para que se ejecute antes o despu&amp;eacute;s del c&amp;oacute;digo que contenga la clase en particular. Esto, si lo combinamos con los atributos nos proporciona unas capacidades potent&amp;iacute;simas para poder tener &lt;a href="http://es.wikipedia.org/wiki/Programaci%C3%B3n_Orientada_a_Aspectos"&gt;programaci&amp;oacute;n orientada a aspectos&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Vamos a ver como realizar esta t&amp;eacute;cnica usando &lt;a href="http://www.codeplex.com/unity/"&gt;Unity&lt;/a&gt;, pero no es exclusiva de este contenedor de IoC, otros contenedores como &lt;a href="http://www.castleproject.org/container/index.html"&gt;Windsor&lt;/a&gt; tambi&amp;eacute;n tienen esta capacidad.&lt;/p&gt;
&lt;p&gt;El mecanismo en Unity que nos permite generar proxies a partir de clases del usuario, se llama intercepci&amp;oacute;n. Cuando creamos una intercepci&amp;oacute;n en Unity debemos definir b&amp;aacute;sicamente dos cosas:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Qu&amp;eacute;&lt;/em&gt; ocurre cuando un m&amp;eacute;todo es interceptado (la pol&amp;iacute;tica de intercepci&amp;oacute;n).&lt;/li&gt;
&lt;li&gt;&lt;em&gt;C&amp;oacute;mo&lt;/em&gt; se intercepta un m&amp;eacute;todo (el interceptor).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Vamos a ver paso a paso como funciona el mecanimso.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Preparaci&amp;oacute;n del entorno&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Vamos a crear una aplicaci&amp;oacute;n de consola, y a&amp;ntilde;adimos las referencias a todos los ensamblados de Unity.&lt;/p&gt;
&lt;p&gt;Luego vamos a crear una interfaz, y la clase que vamos a interceptar:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="background:black;color:#3e60fd;"&gt;public interface &lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;IMyInterface
&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;{
&lt;/span&gt;&lt;span style="background:black;color:#3e60fd;"&gt;&lt;span style="color:#c0c0c0;"&gt;    &lt;/span&gt;string &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;SomeProperty &lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;{ &lt;/span&gt;&lt;span style="background:black;color:#3e60fd;"&gt;get&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;; &lt;/span&gt;&lt;span style="background:black;color:#3e60fd;"&gt;set&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;; }
}
&lt;/span&gt;&lt;span style="background:black;color:#3e60fd;"&gt;public class &lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;MyClass &lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;: &lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;IMyInterface
&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;{
&lt;/span&gt;&lt;span style="background:black;color:#3e60fd;"&gt;&lt;span style="color:#c0c0c0;"&gt;    &lt;/span&gt;public string &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;SomeProperty &lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;{ &lt;/span&gt;&lt;span style="background:black;color:#3e60fd;"&gt;get&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;; &lt;/span&gt;&lt;span style="background:black;color:#3e60fd;"&gt;set&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;; }
}&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Finalmente, en el m&amp;eacute;todo Main() creamos un contenedor de Unity y registramos el mapping entre la interfaz y el tipo:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="background:black;color:#3e60fd;"&gt;static void &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;Main&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;(&lt;/span&gt;&lt;span style="background:black;color:#3e60fd;"&gt;string&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;[] &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;args&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;)
{
&lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;&lt;span style="color:#c0c0c0;"&gt;    &lt;/span&gt;UnityContainer &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;uc &lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;= &lt;/span&gt;&lt;span style="background:black;color:#3e60fd;"&gt;new &lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;UnityContainer&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;();
    &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;uc&lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;.&lt;/span&gt;&lt;span style="background:black;color:white;"&gt;RegisterType&lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;IMyInterface&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;, &lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;MyClass&lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;();
}&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ahora estamos listos para empezar!!!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Configuraci&amp;oacute;n de Unity para que use un interceptor&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Vamos a configurar Unity para que use un interceptor cuando se resuelva la interfaz IMyInterface. Para ello, primero debemos a&amp;ntilde;adir la extensi&amp;oacute;n de intercepci&amp;oacute;n a Untiy y luego configurarla:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="background:black;color:#3e60fd;"&gt;static void &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;Main&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;(&lt;/span&gt;&lt;span style="background:black;color:#3e60fd;"&gt;string&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;[] &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;args&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;)
{
&lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;&lt;span style="color:#c0c0c0;"&gt;    &lt;/span&gt;UnityContainer &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;uc &lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;= &lt;/span&gt;&lt;span style="background:black;color:#3e60fd;"&gt;new &lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;UnityContainer&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;();
    &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;uc&lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;.&lt;/span&gt;&lt;span style="background:black;color:white;"&gt;RegisterType&lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;IMyInterface&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;, &lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;MyClass&lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;();
    &lt;/span&gt;&lt;span style="background:#151515;color:green;"&gt;// A&amp;ntilde;adimos la extensi&amp;oacute;n de intercepci&amp;oacute;n
&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;    &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;uc&lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;.&lt;/span&gt;&lt;span style="background:black;color:white;"&gt;AddNewExtension&lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;Interception&lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;();
    &lt;/span&gt;&lt;span style="background:#151515;color:green;"&gt;// La configuramos para que nos devuelva
&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;    &lt;/span&gt;&lt;span style="background:#151515;color:green;"&gt;// un TransparentProxy cuando resolvamos &lt;/span&gt;&lt;span style="background:#151515;color:green;"&gt;IMyInterface
&lt;/span&gt;&lt;span style="background:black;color:white;"&gt;&lt;span style="color:#c0c0c0;"&gt;    &lt;/span&gt;uc&lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;.&lt;/span&gt;&lt;span style="background:black;color:white;"&gt;Configure&lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;Interception&lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;()&lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;.
    &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;SetInterceptorFor&lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;IMyInterface&lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;&amp;gt;
        &lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;(&lt;/span&gt;&lt;span style="background:black;color:#3e60fd;"&gt;new &lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;TransparentProxyInterceptor&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;());
    &lt;/span&gt;&lt;span style="background:black;color:#3e60fd;"&gt;var &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;u &lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;= &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;uc&lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;.&lt;/span&gt;&lt;span style="background:black;color:white;"&gt;Resolve&lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;IMyInterface&lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;();
    &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;u&lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;.&lt;/span&gt;&lt;span style="background:black;color:white;"&gt;SomeProperty &lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;= &lt;/span&gt;&lt;span style="background:black;color:gray;"&gt;&amp;quot;test&amp;quot;&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;;
}&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Vamos a meter un breakpoint en la &amp;uacute;ltima l&amp;iacute;nea y a ejecutar el c&amp;oacute;digo, para ver si Unity ha echo algo:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/image_5F00_0969ACC8.png"&gt;&lt;img height="90" width="454" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/image_5F00_thumb_5F00_42A5351F.png" alt="image" border="0" title="image" style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Vaya&amp;hellip; pues no parece que haya hecho nada, la verdad. La variable u es de tipo MyClass, no parece haber ning&amp;uacute;n proxy por ah&amp;iacute;&amp;hellip;&lt;/p&gt;
&lt;p&gt;Es normal, ya que hemos configurado Unity para que use un TransparentProxy al resolver la interfaz IMyInterface, pero no lo hemos dicho &lt;em&gt;que&lt;/em&gt; debe hacer Unity con este proxy, as&amp;iacute; que simplemente para no hacer nada, no crea ni el proxy&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Crear el interceptor&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Ha llegado el momento de crear un interceptor, que defina &lt;em&gt;que&lt;/em&gt; ocurre cuando se intercepta un m&amp;eacute;todo o propiedad de la clase. Para ello vamos a crear una clase nueva que implementa la interfaz ICallHandler:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="background:black;color:#3e60fd;"&gt;public class &lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;MyHandler &lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;: &lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;ICallHandler
&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;{
&lt;/span&gt;&lt;span style="background:black;color:#3e60fd;"&gt;&lt;span style="color:#c0c0c0;"&gt;    &lt;/span&gt;public &lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;IMethodReturn &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;Invoke&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;(&lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;IMethodInvocation &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;input&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;, &lt;br /&gt;        &lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;GetNextHandlerDelegate &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;getNext&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;)
    {
        &lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;IMethodReturn &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;msg &lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;= &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;getNext&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;()(&lt;/span&gt;&lt;span style="background:black;color:white;"&gt;input&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;, &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;getNext&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;);
        &lt;/span&gt;&lt;span style="background:black;color:#3e60fd;"&gt;return &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;msg&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;;
     }
        &lt;/span&gt;&lt;span style="background:black;color:#3e60fd;"&gt;public int &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;Order &lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;{ &lt;/span&gt;&lt;span style="background:black;color:#3e60fd;"&gt;get&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;; &lt;/span&gt;&lt;span style="background:black;color:#3e60fd;"&gt;set&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;; }
    }&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Esta es la implementaci&amp;oacute;n &lt;em&gt;b&amp;aacute;sica&lt;/em&gt; por defecto de ICallHandler: no estamos haciendo nada, salvo pasar la llamada a la propiedad &lt;em&gt;real&lt;/em&gt; de la clase. Es decir, nuestro interceptor no est&amp;aacute; haciendo realmente nada.&lt;/p&gt;
&lt;p&gt;Podemos a&amp;ntilde;adir aqu&amp;iacute; el c&amp;oacute;digo que queramos, p.ej:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="background:black;color:#3e60fd;"&gt;public &lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;IMethodReturn &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;Invoke&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;(&lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;IMethodInvocation &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;input&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;, &lt;br /&gt;     &lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;GetNextHandlerDelegate &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;getNext&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;)
{
&lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;&lt;span style="color:#c0c0c0;"&gt;    &lt;/span&gt;Console&lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;.&lt;/span&gt;&lt;span style="background:black;color:white;"&gt;WriteLine&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;(&lt;/span&gt;&lt;span style="background:black;color:gray;"&gt;&amp;quot;Se ha llamado {0} con valor {1}&amp;quot;&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;, &lt;br /&gt;     &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;input&lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;.&lt;/span&gt;&lt;span style="background:black;color:white;"&gt;MethodBase&lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;.&lt;/span&gt;&lt;span style="background:black;color:white;"&gt;Name&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;, &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;input&lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;.&lt;/span&gt;&lt;span style="background:black;color:white;"&gt;Inputs&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;[&lt;/span&gt;&lt;span style="background:black;color:yellow;"&gt;0&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;]);
    &lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;IMethodReturn &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;msg &lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;= &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;getNext&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;()(&lt;/span&gt;&lt;span style="background:black;color:white;"&gt;input&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;, &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;getNext&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;);
&lt;/span&gt;&lt;span style="background:black;color:#3e60fd;"&gt;&lt;span style="color:#c0c0c0;"&gt;    &lt;/span&gt;return &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;msg&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;;
}&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. Indicar que m&amp;eacute;todos / propiedades queremos interceptar&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Tenemos a Unity configurado para usar intercepci&amp;oacute;n, y un interceptor creado&amp;hellip; ahora nos queda finalmente vincular este interceptor con las propiedades o m&amp;eacute;todos que deseemos.&lt;/p&gt;
&lt;p&gt;Para ello podemos usar los atributos: la idea es &lt;em&gt;decorar&lt;/em&gt; cada propiedad o m&amp;eacute;todo con un atributo que indique &lt;em&gt;que&lt;/em&gt; interceptor se usa para dicha propiedad y adem&amp;aacute;s configure dicho interceptor. As&amp;iacute;, generalmente, vamos a usar un atributo para cada interceptor. En nuestro caso tenemos un s&amp;oacute;lo interceptor (MyHandler), as&amp;iacute; que a&amp;ntilde;adiremos un atributo MyHandlerAttribute.&lt;/p&gt;
&lt;p&gt;Para ello vamos a crear una clase que derive de HandlerAttribute (la cual a su vez deriva de Attribute), y redefinir el m&amp;eacute;todo CreateHandler. En este m&amp;eacute;todo debemos devolver el Handler que deseemos:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="background:black;color:silver;"&gt;[&lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;AttributeUsage&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;(&lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;AttributeTargets&lt;/span&gt;&lt;span style="background:black;color:cyan;"&gt;.&lt;/span&gt;&lt;span style="background:black;color:white;"&gt;Property&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;)]
&lt;/span&gt;&lt;span style="background:black;color:#3e60fd;"&gt;class &lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;MyHandlerAttribute &lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;: &lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;HandlerAttribute
&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;{
&lt;/span&gt;&lt;span style="background:black;color:#3e60fd;"&gt;&lt;span style="color:#c0c0c0;"&gt;    &lt;/span&gt;public override &lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;ICallHandler &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;CreateHandler&lt;br /&gt;        &lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;(&lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;IUnityContainer &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;container&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;)
    {
        &lt;/span&gt;&lt;span style="background:black;color:#3e60fd;"&gt;return new &lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;MyHandler&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;();
    }
}&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;En este caso nuestro atributo es trivial, pero en otros casos el atributo puede tener par&amp;aacute;metros (y pas&amp;aacute;rselos al constructor del interceptor, o incluso crear un interceptor u otro en funci&amp;oacute;n de dichos par&amp;aacute;metros).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. Aplicar el atributo a las propiedades que deseemos&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Para ello simplemente decoramos las propiedades (o m&amp;eacute;todos) que deseemos con el atributo:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="background:black;color:#3e60fd;"&gt;public class &lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;MyClass &lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;: &lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;IMyInterface
&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;{
    [&lt;/span&gt;&lt;span style="background:black;color:#2b91af;"&gt;MyHandler&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;]
    &lt;/span&gt;&lt;span style="background:black;color:#3e60fd;"&gt;public string &lt;/span&gt;&lt;span style="background:black;color:white;"&gt;SomeProperty &lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;{ &lt;/span&gt;&lt;span style="background:black;color:#3e60fd;"&gt;get&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;; &lt;/span&gt;&lt;span style="background:black;color:#3e60fd;"&gt;set&lt;/span&gt;&lt;span style="background:black;color:silver;"&gt;; }
}&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Y&amp;hellip;. ya hemos terminado! Si colocamos un breakpoint en el mismo lugar de antes, veremos que ahora si que Unity nos ha creado un proxy:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/image_5F00_41CF5FE6.png"&gt;&lt;img height="88" width="508" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/image_5F00_thumb_5F00_70B7332C.png" alt="image" border="0" title="image" style="border-bottom:0px;border-left:0px;display:inline;border-top:0px;border-right:0px;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;Y si ejecutamos el programa, ver&amp;eacute;is como la salida por pantalla es la siguiente:&lt;/p&gt;
&lt;table border="1"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;pre&gt;Se ha llamado set_SomeProperty con valor test&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Nuestro interceptor ha sido llamado&amp;hellip; hemos triunfado!!! ;-)&lt;/p&gt;
&lt;p&gt;Si a&amp;ntilde;ad&amp;iacute;s una propiedad extra a la interfaz (y a la clase) y NO la decor&amp;aacute;is con el atributo ver&amp;eacute;is que, obviamente dicha propiedad NO es interceptada.&lt;/p&gt;
&lt;p&gt;Esta t&amp;eacute;cnica tiene unas posibilidades &lt;strong&gt;brutales&lt;/strong&gt;&amp;hellip; a mi se me ocurren a brote pronte, temas de logging, seguridad, validaci&amp;oacute;n de propiedades&amp;hellip; vamos, todo aquello en lo que es aplicable la programaci&amp;oacute;n orientada a aspectos!&lt;/p&gt;
&lt;p&gt;Un saludo a todos! ;-)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=156639" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/etomas/archive/tags/patrones/default.aspx">patrones</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/IoC/default.aspx">IoC</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/unity/default.aspx">unity</category></item><item><title>Como independizar tu capa de lógica de tu capa de presentación…</title><link>http://geeks.ms/blogs/etomas/archive/2009/09/17/como-independizar-tu-capa-de-l-243-gica-de-tu-capa-de-presentaci-243-n.aspx</link><pubDate>Thu, 17 Sep 2009 16:36:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:156000</guid><dc:creator>Eduard Tomàs i Avellana</dc:creator><slash:comments>16</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/etomas/rsscomments.aspx?PostID=156000</wfw:commentRss><comments>http://geeks.ms/blogs/etomas/archive/2009/09/17/como-independizar-tu-capa-de-l-243-gica-de-tu-capa-de-presentaci-243-n.aspx#comments</comments><description>&lt;p&gt;A raiz del &lt;a href="http://geeks.ms/blogs/oalvarez/archive/2009/09/09/controles-wpf-en-winforms.aspx"&gt;siguiente post&lt;/a&gt; del excelente &lt;a href="http://geeks.ms/blogs/oalvarez/default.aspx"&gt;blog de Oskar&lt;/a&gt;, &lt;a href="http://yodesarrollador.com/"&gt;Julio Trujillo&lt;/a&gt; coment&amp;oacute; en un comentario (copio literalmente) &amp;ldquo;&lt;em&gt;Ser&amp;iacute;a interesante una explicaci&amp;oacute;n de como convertir Forms a WPF o al menos como poder dise&amp;ntilde;ar una capa que permita conectar la capa de negocio a una de WPF o Forms indistintamente&lt;/em&gt;&amp;rdquo;. A este comentario respond&amp;iacute; yo con unas cuantas ideas, pero luego Julio pidi&amp;oacute; a ver si podiamos exponer las &amp;ldquo;buenas pr&amp;aacute;cticas&amp;rdquo; e incluso un ejemplo&amp;hellip; Julio, no respond&amp;iacute; a tu comentario, simplemente porque el tema es demasiado para un simple comentario, y se merece al menos un post&amp;hellip; y estaba sacando tiempo ;)&lt;/p&gt;
&lt;p&gt;Creo que el comentario de Julio, encerraba dos preguntas en una: c&amp;oacute;mo se puede convertir &lt;em&gt;f&amp;aacute;cilmente&lt;/em&gt; nuestras aplicaciones winforms a wpf y por otro como reaprovechar el m&amp;aacute;ximo c&amp;oacute;digo posible. Voy a exponer unas cuantas ideas que quiz&amp;aacute; os pueden ayudar pero que se resumen en dos: usad una arquitectura n-layer (por cierto que nosotros hablamos s&amp;oacute;lo de &amp;ldquo;n-capas&amp;rdquo; pero &lt;a href="http://icomparable.blogspot.com/2008/10/arquitectura-n-tier-o-arquitectura-n.html"&gt;no confundais n-layer con n-tier&lt;/a&gt;), por un lado y el patr&amp;oacute;n &lt;a href="http://martinfowler.com/eaaDev/SeparatedPresentation.html"&gt;separated presentation&lt;/a&gt; por el otro&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Arquitectura n-layer&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;En esta arquitectura, b&amp;aacute;sicamente, distribuimos nuestro c&amp;oacute;digo en n-capas l&amp;oacute;gicas, donde n suele tener un valor cercano a 3: la separaci&amp;oacute;n &lt;em&gt;cl&amp;aacute;sica&lt;/em&gt; es presentaci&amp;oacute;n, l&amp;oacute;gica y datos. Aunque se pueden meter m&amp;aacute;s (o menos, igual podemos prescindir de la capa de datos) capas l&amp;oacute;gicas (como p.ej. &lt;a href="http://www.exforsys.com/tutorials/application-development/n-tier-architecture-presentation-logic-layer.html"&gt;l&amp;oacute;gica de presentaci&amp;oacute;n&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Una arquitectura n-layer nos ayudar&amp;aacute; a reaprovechar nuestro c&amp;oacute;digo de la capa l&amp;oacute;gica con independencia de la capa de presentaci&amp;oacute;n que tengamos&amp;hellip; Para ello basta seguir dos reglas que nos indicar&amp;aacute;n si vamos por buen camino:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Nuestra capa de l&amp;oacute;gica debe estar en un proyecto separado (una librer&amp;iacute;a de clases). Puede haber (y generalmente habr&amp;aacute;) una referencia desde el proyecto que sea la capa de presentaci&amp;oacute;n al proyecto que es la capa de l&amp;oacute;gica &lt;strong&gt;pero nunca debe aparecer&lt;/strong&gt; una referencia a la capa de l&amp;oacute;gica que vaya hacia la capa de presentaci&amp;oacute;n.&lt;/li&gt;
&lt;li&gt;El proyecto que contiene nuestra capa l&amp;oacute;gica no debe tener nunca ninguna referencia a ning&amp;uacute;n ensamblado de .NET que dependa, directa o indirectamente, de Winforms o WPF&amp;hellip; P.ej. si te aparece una referencia a System.Windows.Forms&amp;hellip; mal, porque est&amp;aacute;s ligando tu capa de l&amp;oacute;gica a una &lt;em&gt;tecnolog&amp;iacute;a de presentaci&amp;oacute;n&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;La comunicaci&amp;oacute;n desde la capa de presentaci&amp;oacute;n a la capa l&amp;oacute;gica &lt;em&gt;puede&lt;/em&gt; ser acoplada: l&amp;oacute;gico, disponemos de una referencia en la capa de presentaci&amp;oacute;n a la capa l&amp;oacute;gica y por lo tanto podemos instanciar cualquier clase p&amp;uacute;blica de la capa de l&amp;oacute;gica y llamar a sus m&amp;eacute;todos directamente.&lt;/p&gt;
&lt;p&gt;La comunicaci&amp;oacute;n desde la capa l&amp;oacute;gica a la capa de presentaci&amp;oacute;n &lt;strong&gt;debe&lt;/strong&gt; ser desacoplada: no tenemos otra opci&amp;oacute;n, dado que no podemos tener ninguna referencia a la capa de presentaci&amp;oacute;n desde la capa l&amp;oacute;gica. Aqu&amp;iacute; tenemos tres alternativas v&amp;aacute;lidas:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Comunicaci&amp;oacute;n pasiva: es decir, la capa de l&amp;oacute;gica se limita a devolver toda la informaci&amp;oacute;n que la capa de presentaci&amp;oacute;n solicita mediante los valores de retorno de los m&amp;eacute;todos. As&amp;iacute;, la comunicaci&amp;oacute;n la inicia siempre la capa de presentaci&amp;oacute;n.&lt;/li&gt;
&lt;li&gt;Eventos, o cualquier mecanismo similar (como &lt;a href="http://en.wikipedia.org/wiki/Command_pattern"&gt;commands&lt;/a&gt;): Cuando la capa de l&amp;oacute;gica quiere informar de algo a la capa de presentaci&amp;oacute;n, lanza eventos a los que est&amp;aacute; suscrita la capa de presentaci&amp;oacute;n y esta act&amp;uacute;a en consecuencia. Esto permite que la capa l&amp;oacute;gica realice env&amp;iacute;os de informaci&amp;oacute;n a la capa l&amp;oacute;gica sin ser necesario que esta &amp;uacute;ltima inicie la comunicaci&amp;oacute;n.&lt;/li&gt;
&lt;li&gt;Utilizar interfaces junto con un patr&amp;oacute;n &lt;em&gt;&lt;a href="http://martinfowler.com/articles/injection.html#UsingAServiceLocator"&gt;service locator&lt;/a&gt;&lt;/em&gt;. Esta alternativa precisa el uso de &lt;a href="http://weblogs.asp.net/sfeldman/archive/2008/02/14/understanding-ioc-container.aspx"&gt;un contenedor IoC&lt;/a&gt; (como &lt;a href="http://www.codeplex.com/unity"&gt;Unity&lt;/a&gt; o &lt;a href="http://www.castleproject.org/container/index.html"&gt;Windsor&lt;/a&gt;), as&amp;iacute; como la aparici&amp;oacute;n de un &lt;em&gt;tercer&lt;/em&gt; assembly destinado a contener las interfaces. Usando esta aproximaci&amp;oacute;n, las clases de la capa de presentaci&amp;oacute;n implementan todas ellas las interfaces (definidas en el assembly aparte) y la capa de l&amp;oacute;gica obtiene referencias a los objetos de la capa de presentaci&amp;oacute;n usando las interfaces y el contenedor de IoC. Esta alternativa permite una conversaci&amp;oacute;n &amp;ldquo;tu-a-tu&amp;rdquo; con la capa de presentaci&amp;oacute;n.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Por supuesto las tres alternativas pueden combinarse.&lt;/p&gt;
&lt;p&gt;Esto independiza nuestra capa de l&amp;oacute;gica (y de datos) de la presentaci&amp;oacute;n usada. Si alguna vez queremos migrar nuestra aplicaci&amp;oacute;n, p.ej. de winforms a wpf, s&amp;oacute;lo deberemos reescribir la capa de presentaci&amp;oacute;n&amp;hellip; lo que seg&amp;uacute;n como est&amp;eacute; dise&amp;ntilde;ada puede ser un trabajo asumible o una obra de titanes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Separated Presentation&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Bajo este nombre se agrupan multitud de patrones (&lt;a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller"&gt;MVC&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/magazine/cc188690.aspx"&gt;MVP&lt;/a&gt;, &lt;a href="http://msdn.microsoft.com/en-us/magazine/dd419663.aspx"&gt;MVVM&lt;/a&gt;), pero todos ellos coinciden en lo b&amp;aacute;sico: separa &lt;strong&gt;siempre&lt;/strong&gt; tu c&amp;oacute;digo que &lt;em&gt;muestra&lt;/em&gt; los datos (el formulario) del c&amp;oacute;digo que indica cuando y como debe mostrarlos.&lt;/p&gt;
&lt;p&gt;Lamentablemente, desde los tiempos de Visual Basic, Microsoft nos acostumbra a desarrollar usando el &amp;ldquo;patr&amp;oacute;n formulario&amp;rdquo;, que b&amp;aacute;sicamente consiste en crear un form, rellenar-lo de controles y asociar eventos a funciones tipo MyButton_Click() que contendr&amp;aacute;n todo el c&amp;oacute;digo. Este modelo es r&amp;aacute;pido, f&amp;aacute;cil de entender y produce buenos resultados&amp;hellip; hasta que uno debe empezar a cambiar cosas. A lo mejor al cabo de unos meses en tu aplicaci&amp;oacute;n le aparece &lt;em&gt;otro&lt;/em&gt; formulario que se parece &lt;em&gt;mucho&lt;/em&gt; a un formulario ya existente pero a lo mejor muestra un par de controles m&amp;aacute;s o se comporta ligeramente distinto&amp;hellip; O bien haces copy-paste del primer formulario en uno nuevo y lo modificas (funciona pero luego vas a mantener dos formularios parecidos) o empiezas a meter &lt;em&gt;ifs&lt;/em&gt; en el primer formulario hasta que todo se vuelve un galimat&amp;iacute;as.&lt;/p&gt;
&lt;p&gt;Cr&amp;eacute;eme: Olvida el &amp;ldquo;patr&amp;oacute;n formulario&amp;rdquo; cuanto antes. Sirve para &lt;em&gt;peque&amp;ntilde;as&lt;/em&gt; aplicaciones que no precisen un mantenimiento excesivo, pero para aplicaciones mayores usa alguna variante de &lt;em&gt;separated presentation&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Si nos centramos en el caso concreto de Winforms y WPF, una de las mejores elecciones es MVP: si &lt;strong&gt;ya sabes&lt;/strong&gt; que tu aplicaci&amp;oacute;n deber&amp;aacute; ser migrada (o bien debe ser multi-presentaci&amp;oacute;n) entonces MVP te ahorrar&amp;aacute; bastante trabajo: &amp;ldquo;b&amp;aacute;sicamente&amp;rdquo; s&amp;oacute;lo deber&amp;aacute;s redise&amp;ntilde;ar los formularios y podr&amp;aacute;s aprovechar el modelo y los presenters. Yo por ejemplo suelo usar &lt;em&gt;siempre&lt;/em&gt; MVP cuando desarrollo en Winforms (no por temas de migraci&amp;oacute;n, sino porque considero que es el patr&amp;oacute;n que aplica mejor) y cuando estoy en WPF uso MVVM o MVP dependiendo de la ocasi&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;Reconozco que si se debiera migrar una aplicaci&amp;oacute;n WPF creada usando MVVM a winforms habr&amp;iacute;a bastante trabajo, pero de todos modos muchas veces si se migra una aplicaci&amp;oacute;n a una tecnolog&amp;iacute;a de presentaci&amp;oacute;n nueva es para aprovechar las nuevas capacidades (me cuesta imaginarme una migraci&amp;oacute;n de WPF a winforms, mientras que al rev&amp;eacute;s puede ser m&amp;aacute;s habitual).&lt;/p&gt;
&lt;p&gt;En fin, migrar una aplicaci&amp;oacute;n a otra tecnolog&amp;iacute;a de presentaci&amp;oacute;n &lt;strong&gt;siempre cuesta trabajo&lt;/strong&gt;, pero si separamos bien las capas (n-layer) y organizamos bien nuestra capa de presentaci&amp;oacute;n (separated presentation) tendremos mucho de ganado&amp;hellip;&lt;/p&gt;
&lt;p&gt;Saludos!!!!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=156000" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/etomas/archive/tags/patrones/default.aspx">patrones</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/opinion/default.aspx">opinion</category></item><item><title>La sencillez de una interfaz compleja</title><link>http://geeks.ms/blogs/etomas/archive/2009/03/12/la-sencillez-de-una-interfaz-compleja.aspx</link><pubDate>Thu, 12 Mar 2009 10:11:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:144749</guid><dc:creator>Eduard Tomàs i Avellana</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/etomas/rsscomments.aspx?PostID=144749</wfw:commentRss><comments>http://geeks.ms/blogs/etomas/archive/2009/03/12/la-sencillez-de-una-interfaz-compleja.aspx#comments</comments><description>&lt;p&gt;Hace alg&amp;uacute;n tiempecillo escrib&amp;iacute; un art&amp;iacute;culo para el e-zine de &lt;a href="http://www.raona.com/"&gt;raona&lt;/a&gt;, que enviamos a distintos clientes. En el art&amp;iacute;culo esbozaba los patrones b&amp;aacute;sicos para dise&amp;ntilde;ar interfaces de usuario compuestas. Posteriormente me surgi&amp;oacute; la idea de que una ampliaci&amp;oacute;n de dicho art&amp;iacute;culo, donde se mostrasen ejemplos en &lt;a href="http://www.codeplex.com/CompositeWPF"&gt;PRISM&lt;/a&gt; y WPF de estos conceptos podr&amp;iacute;a ser interesante. Afortunadamente en &lt;a href="http://www.dotnetmania.com/"&gt;DotNetMania&lt;/a&gt; pensaron lo mismo y es por ello que en la revista de este marzo hay un art&amp;iacute;culo con este mismo t&amp;iacute;tulo.&lt;/p&gt;
&lt;p&gt;Lo que ahora sigue &amp;eacute;s el &lt;strong&gt;&lt;span style="text-decoration:underline;"&gt;art&amp;iacute;culo original&lt;/span&gt;&lt;/strong&gt;, el que escrib&amp;iacute; para el e-zine. Aunque el de DotNetMania describe las mismas ideas, ambos art&amp;iacute;culos tienen poco a ver (tanto en contenido, como en enfoque como en extensi&amp;oacute;n). Como creo que el art&amp;iacute;culo del e-zine tambi&amp;eacute;m tiene su inter&amp;eacute;s, me he tomado la libertad de postearlo aqu&amp;iacute; :)&lt;/p&gt;
&lt;p&gt;PD: Por si os interesa, los distintos e-zines que vamos sacando en raona, los podeis consultar en la &lt;a href="http://www.raona.com/Not&amp;iacute;cies/ezine/tabid/110/Default.aspx"&gt;secci&amp;oacute;n de ezines de raona&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;La sencillez de una interfaz compleja (versi&amp;oacute;n e-zine).&lt;/h3&gt;
&lt;p&gt;Cada vez las aplicaciones son m&amp;aacute;s y m&amp;aacute;s complejas, y los usuarios son m&amp;aacute;s y m&amp;aacute;s exigentes. Los desarrolladores debemos afrontar este doble reto siendo capaces de proporcionar mejores y m&amp;aacute;s complejas aplicaciones, en cada vez menos tiempo. Evidentemente este es un proceso global, que afecta a todo el desarrollo de una soluci&amp;oacute;n de software, pero me gustar&amp;iacute;a centrarme en los retos concretos que esto implica cuando hablamos de interfaces de usuario. No en vano, la interfaz de usuario es el punto de conexi&amp;oacute;n entre el usuario y la aplicaci&amp;oacute;n. Es un elemento cr&amp;iacute;tico y de su implementaci&amp;oacute;n depende en buena medida el &amp;eacute;xito final de toda la aplicaci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Interfaces complejas&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Las aplicaciones actuales demandan interfaces de usuario complejas a nivel t&amp;eacute;cnico pero que a la vez sean sencillas de utilizar y de mantener. Que se adapten a cualquier tipo de usuario, que tanto usuarios expertos como inexpertos se sientan a gusto utiliz&amp;aacute;ndola. En resumen que la experiencia del usuario al utilizar la interfaz sea plena y que nuestra aplicaci&amp;oacute;n sea usable por cualquier usuario.&lt;/p&gt;
&lt;p&gt;El t&amp;eacute;rmino &lt;i&gt;interfaz compleja&lt;/i&gt;, no quiere referirse al aspecto visual o usable si no al hecho de que cada vez es m&amp;aacute;s complejo y dif&amp;iacute;cil realizar interfaces que permitan conjugar las crecientes posibilidades de la aplicaci&amp;oacute;n con la sencillez de uso y la usabilidad. Este es el reto que debemos solucionar.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Nuevas tecnolog&amp;iacute;as, nuevas posibilidades&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Con la aparici&amp;oacute;n de WPF, Microsoft ha dotado a los desarrolladores de un mont&amp;oacute;n de nuevas posibilidades para la construcci&amp;oacute;n de interfaces. El hecho de disponer de un lenguaje declarativo (XAML) para definir las interfaces permite la separaci&amp;oacute;n entre dos roles b&amp;aacute;sicos hoy en d&amp;iacute;a: los dise&amp;ntilde;adores y los desarrolladores. Pero separar desarrolladores y dise&amp;ntilde;adores es s&amp;oacute;lo un primer paso (un primer gran paso) pero no soluciona la problem&amp;aacute;tica de fondo: el modo en c&amp;oacute;mo est&amp;aacute;n dise&amp;ntilde;adas y desarrolladas las interfaces de usuario.&lt;/p&gt;
&lt;p&gt;El mecanismo habitual de desarrollar interfaces de usuario en .NET, viene influenciado de los tiempos de Visual Basic. Es un patr&amp;oacute;n que consiste en una clase contenedora (llamada com&amp;uacute;nmente formulario) que contiene a los controles y toda la l&amp;oacute;gica asociada a dichos controles. Por norma general el formulario se suscribe a los eventos de los controles a los que contiene y realiza la l&amp;oacute;gica apropiada en las funciones gestoras de dichos eventos. La ventaja de este modelo de programaci&amp;oacute;n es que es sencillo, intuitivo y f&amp;aacute;cil de aprender. Las desventajas son que al tener unidas la l&amp;oacute;gica con la presentaci&amp;oacute;n se vuelve m&amp;aacute;s complejo el mantenimiento tendiendo a &lt;i&gt;colapsar&lt;/i&gt; en grandes proyectos y se dificulta la separaci&amp;oacute;n del desarrollo entre varios equipos.&lt;/p&gt;
&lt;p&gt;Una de las claves para desarrollar interfaces de usuario complejas y que resulten mantenibles es desacoplar la presentaci&amp;oacute;n de la l&amp;oacute;gica de dicha presentaci&amp;oacute;n. WPF presenta algunas novedades que ayudan a conseguir dicho desacople:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Commands: Permite desacoplar los eventos de los controles de la gesti&amp;oacute;n de dichos eventos y unificar en un mismo punto la gesti&amp;oacute;n de distintos eventos de distintos controles pero que realizan la misma acci&amp;oacute;n (p.ej. un bot&amp;oacute;n de una toolbar y una entrada de men&amp;uacute;). &lt;/li&gt;
&lt;li&gt;Routed Events: Permiten tratar en un solo contenedor cualquier evento generado por cualquier de los controles &amp;ldquo;hijos&amp;rdquo; (est&amp;eacute;n en el nivel de profundidad que est&amp;eacute;n). &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Estas novedades aunque interesantes, por si solas no son suficientes para desacoplar totalmente la presentaci&amp;oacute;n y su l&amp;oacute;gica. Para ello hace falta un cambio de paradigma, un nuevo modelo.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Composite Application Library&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Composite Application Library (CAL) tambi&amp;eacute;n conocida por su nombre en c&amp;oacute;digo PRISM, es un framework lanzado por la gente de &amp;ldquo;Patterns &amp;amp; Practices&amp;rdquo; para ayudar en la construcci&amp;oacute;n de aplicaciones complejas utilizando WPF.&lt;/p&gt;
&lt;p&gt;CAL se basa en varios patrones para ayudar a conseguir un desacople total entre la presentaci&amp;oacute;n y la l&amp;oacute;gica de presentaci&amp;oacute;n. A continuaci&amp;oacute;n comentaremos tres de los patrones m&amp;aacute;s relevantes de CAL.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Inversion of Control (IoC)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Este patron desacopla una clase en concreto de otra clase de las clases que utiliza, es decir de sus referencias:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/clip_5F00_image002_5F00_5C4307ED.jpg"&gt;&lt;img border="0" width="244" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/clip_5F00_image002_5F00_thumb_5F00_02A77BEA.jpg" alt="Dependencias entre clsases" height="181" style="border-top-width:0px;display:inline;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" title="Dependencias entre clsases" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;La clase ClassA utiliza dos servicios (ServiceA y ServiceB) y por lo tanto tiene referencias directas a ellos. Esto implica, entre otras cosas, que si queremos modificar las referencias debemos modificar el c&amp;oacute;digo fuente de ClassA. Para desacoplar la clase de sus referencias la soluci&amp;oacute;n es a&amp;ntilde;adir un componente externo que se encargue de encontrar y gestionar las referencias de la clase ClassA. En funci&amp;oacute;n de c&amp;oacute;mo dise&amp;ntilde;emos este elemento externo hablaremos de un patr&amp;oacute;n &lt;i&gt;ServiceLocator&lt;/i&gt; o de &lt;i&gt;Dependency Injection&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/clip_5F00_image0024_5F00_2B45E7F1.jpg"&gt;&lt;img border="0" width="491" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas/clip_5F00_image0024_5F00_thumb_5F00_68D5D66B.jpg" alt="Service locator &amp;amp;  Dependency Injection" height="174" style="border-top-width:0px;display:inline;border-left-width:0px;border-bottom-width:0px;border-right-width:0px;" title="Service locator &amp;amp;  Dependency Injection" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Con ServiceLocator la clase ClassA s&amp;oacute;lo contiene una referencia al &lt;i&gt;Locator&lt;/i&gt; siendo esta clase la que obtiene y devuelve la referencia adecuada a la clase. El &lt;i&gt;Locator&lt;/i&gt; NO instancia los servicios, simplemente los localiza (los servicios han estado instanciados previamente por alguien): mientras un servicio est&amp;eacute; registrado, el &lt;i&gt;Locator&lt;/i&gt; lo encontrar&amp;aacute;. CAL utiliza Unity para ofrecer un Service Locator, lo que nos permite instanciar y registrar servicios que luego ser&amp;aacute;n utilizados en cualquier parte de la aplicaci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;Con Dependency Injection, existe un &lt;i&gt;Builder&lt;/i&gt; que crea el objeto del servicio y lo &amp;ldquo;incrusta&amp;rdquo; en alguna propiedad espec&amp;iacute;fica de la clase ClassA (o bien en alg&amp;uacute;n par&amp;aacute;metro del constructor). CAL utiliza Unity para proporcionar Dependency Injection.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Separated Presentation&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Si IoC nos permite desacoplar nuestras clases de las referencias que necesitan, el conjunto de patrones conocidos como &amp;ldquo;separated presentation&amp;rdquo;, nos permiten separar la presentaci&amp;oacute;n de la parte de la l&amp;oacute;gica que gestiona la presentaci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;Existen varios patrones que implementan &amp;ldquo;separated presentation&amp;rdquo; siendo los m&amp;aacute;s concidos MVP (Model &amp;ndash; View &amp;ndash; Presenter) o MVVM (Model &amp;ndash; View- ViewModel). Debido a las capacidades de WPF se tiende a utilizar m&amp;aacute;s MVVM (mientras que MVP es m&amp;aacute;s frecuente en aplicaciones Windows forms p.ej), debido a que MVVM se basa en uno de los aspectos m&amp;aacute;s potentes de WPF: su data binding.&lt;/p&gt;
&lt;p&gt;El patr&amp;oacute;n MVVM se basa en tres elementos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Vista (View): Contiene los elementos visuales (controles). En el caso de WPF suele estar creada por un dise&amp;ntilde;ador e implementada v&amp;iacute;a XAML &lt;/li&gt;
&lt;li&gt;Modelo (Model): Contiene los datos que muestra la vista. En este punto es cuando se utiliza b&amp;aacute;sicamente el data binding, para enlazar los valores de los controles de la vista a valores de distintos elementos del modelo. &lt;/li&gt;
&lt;li&gt;Modelo de Vista (ViewModel): En interfaces sencillas, la vista se puede enlazar directamente con el modelo, pero en interfaces complejas no suele ser posible. En muchos casos el Modelo puede tener multitud de informaci&amp;oacute;n que no se puede mapear a valores de los controles o bien nuestra vista debe realizar y mantener valores &amp;ldquo;temporales&amp;rdquo; que no forman parte estricta del modelo. Es en estos casos donde entra en escena el &amp;ldquo;ViewModel&amp;rdquo;, actuando de &lt;i&gt;puente&lt;/i&gt; proporcionando transformadores para poder enlazar los controles de la vista y commands para que la vista pueda interactuar con el modelo. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;De esta manera no existe m&amp;aacute;s una clase &amp;ldquo;formulario&amp;rdquo; que contiene los controles y toda la l&amp;oacute;gica asociada a ellos.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Event Aggregator&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Un &lt;i&gt;Event Aggregator&lt;/i&gt; es la implementaci&amp;oacute;n de un modelo de eventos publish and subscribe, donde cuando alquien quiere recibir un evento se &lt;i&gt;suscribe&lt;/i&gt; a este tipo de evento en particular. Cuando alguien quiere enviar un evento lo &lt;i&gt;publica&lt;/i&gt; y el &lt;i&gt;event aggregator&lt;/i&gt; se ocupa de que todos los que se hayan suscrito a este tipo de evento lo reciban. De esta manera se desacoplan totalmente los publicadores de eventos de sus suscriptores.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conclusiones&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Para desarrollar interfaces complejas que a la vez sean amigables para el usuario y mantenibles para el desarrollador es necesario involucrar a los dise&amp;ntilde;adores por un lado y desacoplar la presentaci&amp;oacute;n de la l&amp;oacute;gica que la gestiona por otro. Gracias a XAML, WPF permite que los dise&amp;ntilde;adores se integren totalmente en el ciclo de desarrollo, y el uso de determinados patrones permite desacoplar los distintos elementos que conforman la inferfaz de usuario. CAL es un framework y una gu&amp;iacute;a de estilo que bas&amp;aacute;ndose en dichos patrones y en las funcionalidades inherentes a WPF nos permite desarrollar aplicaciones complejas que sean mantenibles y amigables a la vez.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Referencias&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Command pattern in WPF (&lt;a href="http://www.microsoft.com/belux/msdn/nl/community/columns/jdruyts/wpf_commandpattern.mspx"&gt;http://www.microsoft.com/belux/msdn/nl/community/columns/jdruyts/wpf_commandpattern.mspx&lt;/a&gt;) &lt;/li&gt;
&lt;li&gt;Routed Events overview (&lt;a href="http://msdn.microsoft.com/en-us/library/ms742806.aspx"&gt;http://msdn.microsoft.com/en-us/library/ms742806.aspx&lt;/a&gt;) &lt;/li&gt;
&lt;li&gt;Model &amp;ndash; View &amp;ndash; Presenter pattern (&lt;a href="http://msdn.microsoft.com/en-us/magazine/cc188690.aspx"&gt;http://msdn.microsoft.com/en-us/magazine/cc188690.aspx&lt;/a&gt;) &lt;/li&gt;
&lt;li&gt;Model &amp;ndash; View &amp;ndash; ViewModel pattern (&lt;a href="http://blogs.msdn.com/johngossman/archive/2005/10/08/478683.aspx"&gt;http://blogs.msdn.com/johngossman/archive/2005/10/08/478683.aspx&lt;/a&gt;) &lt;/li&gt;
&lt;li&gt;Inversion of Control (&lt;a href="http://msdn.microsoft.com/en-us/library/cc707904.aspx"&gt;http://msdn.microsoft.com/en-us/library/cc707904.aspx&lt;/a&gt;) &lt;/li&gt;
&lt;li&gt;Service Locator Pattern (&lt;a href="http://msdn.microsoft.com/en-us/library/cc707905.aspx"&gt;http://msdn.microsoft.com/en-us/library/cc707905.aspx&lt;/a&gt;) &lt;/li&gt;
&lt;li&gt;Dependency Injection (&lt;a href="http://msdn.microsoft.com/en-us/library/cc707845.aspx"&gt;http://msdn.microsoft.com/en-us/library/cc707845.aspx&lt;/a&gt;) &lt;/li&gt;
&lt;li&gt;Dependency Injection on Martin Fowler&amp;rsquo;s site (&lt;a href="http://www.martinfowler.com/articles/injection.html"&gt;http://www.martinfowler.com/articles/injection.html&lt;/a&gt;) &lt;/li&gt;
&lt;li&gt;Event Aggregator (&lt;a href="http://martinfowler.com/eaaDev/EventAggregator.html"&gt;http://martinfowler.com/eaaDev/EventAggregator.html&lt;/a&gt;) &lt;/li&gt;
&lt;li&gt;Event Aggregator (&lt;a href="http://msdn.microsoft.com/en-us/library/cc707867.aspx"&gt;http://msdn.microsoft.com/en-us/library/cc707867.aspx&lt;/a&gt;) &lt;/li&gt;
&lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=144749" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/etomas/archive/tags/patrones/default.aspx">patrones</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/IoC/default.aspx">IoC</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/opinion/default.aspx">opinion</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/prism/default.aspx">prism</category></item><item><title>CommandPattern extendiendo Unity</title><link>http://geeks.ms/blogs/etomas/archive/2009/02/13/commandpattern-extendiendo-unity.aspx</link><pubDate>Fri, 13 Feb 2009 12:59:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:142737</guid><dc:creator>Eduard Tomàs i Avellana</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/etomas/rsscomments.aspx?PostID=142737</wfw:commentRss><comments>http://geeks.ms/blogs/etomas/archive/2009/02/13/commandpattern-extendiendo-unity.aspx#comments</comments><description>&lt;p&gt;Hola a todos! Hoy voy a hablar del poder que nos da el mecanismo de extensiones de Unity. Doy por supuesto que todos conoceis lo que es un contenedor IoC en general y Unity en particular. Si no, echad un vistazo a los posts &amp;ldquo;&lt;a href="http://geeks.ms/blogs/etomas/archive/2008/10/28/ioc-o-el-poder-de-ceder-el-control.aspx"&gt;IoC o el poder de ceder el control&lt;/a&gt;&amp;rdquo; (para una explicaci&amp;oacute;n general de IoC) y &amp;ldquo;&lt;a href="http://geeks.ms/blogs/jdieguez/archive/2009/01/25/microsoft-unity-inyecci-243-n-de-dependencias-net.aspx"&gt;Microsoft Unity: Inyecci&amp;oacute;n de dependencias .NET&lt;/a&gt;&amp;rdquo; (para una explicaci&amp;oacute;n general sobre Unity en concreto).&lt;/p&gt;
&lt;p&gt;Para ilustrar el poder que nos da extender Unity voy a poner una &lt;em&gt;posible&lt;/em&gt; implementaci&amp;oacute;n del patron &lt;a href="http://en.wikipedia.org/wiki/Command_pattern"&gt;Command Pattern&lt;/a&gt;. Este patr&amp;oacute;n es un cl&amp;aacute;sico para la construcci&amp;oacute;n de interfaces desacopladas, donde el elemento de la UI que genera una acci&amp;oacute;n y el c&amp;oacute;digo que implementa esta acci&amp;oacute;n no tienen porque estar relacionados. Esto aumenta la mantenibilidad y la reutilizaci&amp;oacute;n del c&amp;oacute;digo.&lt;/p&gt;
&lt;p&gt;Lo que voy a exponer aqu&amp;iacute;, es una implementaci&amp;oacute;n de dicho patr&amp;oacute;n, usando Unity y que funciona con cualquier &amp;ldquo;tecnolog&amp;iacute;a&amp;rdquo; (Winforms, WPF, c&amp;oacute;nsola). Dado que esto va a ser un poco largo, coged &lt;a href="http://www.volldamm.es"&gt;una buena cervecita&lt;/a&gt; que empezamos! ;-)&lt;/p&gt;
&lt;p&gt;Tambi&amp;eacute;n comentaros que el c&amp;oacute;digo que mostrar&amp;eacute;, aunque funcional, no est&amp;aacute; 100% completo, pero tiene las bases para que sea f&amp;aacute;cilmente completable. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Extensiones de Unity&amp;hellip; que son?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Las extensiones de Unity son el mecanismo que nos permite personalizar el comportamiento del contenedor cuando deba crear o destruir un objeto, o bien cuando se registre alg&amp;uacute;n mapping entre tipos. En este post vamos a hablar de dos mecanismos para extender Unity:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Extensiones: Una extensi&amp;oacute;n es &lt;em&gt;b&amp;aacute;sicamente&lt;/em&gt; una clase que deriva de &lt;span style="color:#2b91af;"&gt;UnityContainerExtension&lt;/span&gt;. Cuando se a&amp;ntilde;ade una extensi&amp;oacute;n a Unity (cosa que puede hacerse program&amp;aacute;ticamente o por configuraci&amp;oacute;n), se llama al m&amp;eacute;todo Initialize() de la extensi&amp;oacute;n. Las extensiones se usan para registrar en el contenedor nuevas Estrategias o Pol&amp;iacute;ticas y para suscribirnos a eventos de cuando se registra un mapping entre tipos.&lt;/li&gt;
&lt;li&gt;Estrategias: Una estrategia es &lt;em&gt;algo&lt;/em&gt; que debe hacer Unity antes o despu&amp;eacute;s de crear o destruir un objeto. P.ej. si colocamos un atributo [Dependency] en cualquier propiedad p&amp;uacute;blica de un objeto, Unity nos &lt;em&gt;rellener&amp;aacute;&lt;/em&gt; autom&amp;aacute;ticamente dicha propiedad. Esto se hace a trav&amp;eacute;s de una estrategia (built-in dentro de Unity).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;2. Unity y ObjectBuilder2&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Unity en si mismo, en el fondo es &lt;em&gt;simplemente&lt;/em&gt;, un wrapper sore ObjectBuilder2 (Una evoluci&amp;oacute;n del ObjectBuilder que venia con CAB y EntLib). Aunque por norma general podemos usar Unity sin preocuparnos del ObjectBuilder2 subyacente, cuando nos ponemos a extender el contenedor, entonces si que debemos interactuar con ObjectBuilder2. En concreto las &lt;em&gt;estrategias&lt;/em&gt; se definen siempre a nivel de ObjectBuilder2, mientras que las &lt;em&gt;extensiones&lt;/em&gt; son un mecanismo propio de Unity.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Nuestro modelo de Command Pattern&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Para este ejemplo he pensado en un modelo de command pattern, extremadamente sencillo y declarativo (es decir, basado en atributos). Para ello vamos a usar dos atributos propios:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CommandSource: Para indicar que un determinado evento debe vincularse a un command.&lt;/li&gt;
&lt;li&gt;CommandTarget: Para indicar que un m&amp;eacute;todo es la implementaci&amp;oacute;n de un command.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;El primer atributo se define a nivel de clase (tantas veces como sea necesario), mientras que el segundo se define a nivel de m&amp;eacute;todo (una sola vez).&lt;/p&gt;
&lt;p&gt;Un ejemplo de su uso:&lt;/p&gt;
&lt;pre class="code"&gt;[&lt;span style="color:#2b91af;"&gt;CommandSource&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Command1&amp;quot;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;quot;button1&amp;quot;&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;&amp;quot;Click&amp;quot;&lt;/span&gt;)]
&lt;span style="color:blue;"&gt;public partial class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;View1 &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;UserControl
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public &lt;/span&gt;View1()
    {
        InitializeComponent();
    }
}&lt;/pre&gt;
&lt;p&gt;Cuando se lance el evento &amp;ldquo;Click&amp;rdquo; del objeto &amp;ldquo;button1&amp;rdquo; se debe invocar el command &amp;ldquo;Command1&amp;rdquo;. En alg&amp;uacute;n sitio habr&amp;aacute; una clase (que no debe porque tener ninguna relaci&amp;oacute;n con View1) con el siguiente c&amp;oacute;digo para gestionar el command:&lt;/p&gt;
&lt;pre class="code"&gt;[&lt;span style="color:#2b91af;"&gt;CommandTarget&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Command1&amp;quot;&lt;/span&gt;)]
&lt;span style="color:blue;"&gt;private void &lt;/span&gt;Foo()
{
    &lt;span style="color:#2b91af;"&gt;MessageBox&lt;/span&gt;.Show(&lt;span style="color:#a31515;"&gt;&amp;quot;Command1 Invocado&amp;quot;&lt;/span&gt;);
}&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. Qu&amp;eacute; vamos a hacer&amp;hellip;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Lo que queremos hacer es lo siguiente:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cuando se registre un mapping en Unity, vamos a mirar la clase que se registra para inspeccionar si tiene atributos CommandSource y/o CommandTarget y vamos a guardar esta informaci&amp;oacute;n en una clase (el CommandBroker).&lt;/li&gt;
&lt;li&gt;Cuando se resuelva un tipo (es decir se cree una instancia) vamos a inspeccionar su tipo para ver si tiene atributos CommandSource y/o CommandTarget (s&amp;oacute;lo lo haremos si es necesario, que ser&amp;aacute; si no se hab&amp;iacute;a definido un mapping para este objeto previamente), y luego nos suscribiremos a los eventos necesarios.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As&amp;iacute; el CommandBroker es una clase que:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tiene toda la informaci&amp;oacute;n de que atributos CommandSource y/o CommandTarget tiene cada tipo creado por Unity.&lt;/li&gt;
&lt;li&gt;Se suscribe a todos los eventos que vengan de un CommandSource y ejecuta el CommandTarget asociado.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;El primer punto lo llevaremos a cabo mediante una extensi&amp;oacute;n, y el segundo mediante una estrategia.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. La extensi&amp;oacute;n: CommandExtension&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Vamos a definir nuestra extensi&amp;oacute;n de Unity, para que haga tres cosas principales:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cree una instancia del CommandBroker y la coloque como singleton dentro de Unity.&lt;/li&gt;
&lt;li&gt;Cree la estrategia que necesitaremos y la &amp;ldquo;instale&amp;rdquo; en Unity.&lt;/li&gt;
&lt;li&gt;Se registre al evento de creaci&amp;oacute;n de mapping para poder inspeccionar los tipos (evento Registering).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;El c&amp;oacute;digo es realmente simple:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;public class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;CommandExtension &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;UnityContainerExtension
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;protected override void &lt;/span&gt;Initialize()
    {
        &lt;span style="color:blue;"&gt;this&lt;/span&gt;.Container.RegisterInstance&amp;lt;&lt;span style="color:#2b91af;"&gt;ICommandBroker&lt;/span&gt;&amp;gt;(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;CommandBroker&lt;/span&gt;());
        &lt;span style="color:blue;"&gt;this&lt;/span&gt;.Context.Strategies.Add(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;CommandStrategy&lt;/span&gt;(&lt;span style="color:blue;"&gt;this&lt;/span&gt;.Container), 
            &lt;span style="color:#2b91af;"&gt;UnityBuildStage&lt;/span&gt;.Creation);
        &lt;span style="color:blue;"&gt;this&lt;/span&gt;.Context.Registering += (o, e) =&amp;gt;
            &lt;span style="color:blue;"&gt;this&lt;/span&gt;.Container.Resolve&amp;lt;&lt;span style="color:#2b91af;"&gt;ICommandBroker&lt;/span&gt;&amp;gt;().
            ProcessTypeInfo(e.TypeTo ?? e.TypeFrom);

        }
}&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;El m&amp;eacute;todo &amp;ldquo;ProcessTypeInfo&amp;rdquo; de la clase CommandBroker es la que inspecciona un tipo para ver si tiene atributos CommandSource y CommandTarget.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;6. La estrategia: CommandStrategy&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;En la extensi&amp;oacute;n creada previamente instalamos la estrategia CommandStrategy. Una estrategia se llama cada vez que Unity debe crear (BuildUp) o destruir (TearDown) un objeto.&lt;/p&gt;
&lt;p&gt;En mi caso el c&amp;oacute;digo de la estrategia tambi&amp;eacute;n es realmente simple:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;CommandStrategy &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;IBuilderStrategy
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;private &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IUnityContainer &lt;/span&gt;container;
    &lt;span style="color:blue;"&gt;public &lt;/span&gt;CommandStrategy(&lt;span style="color:#2b91af;"&gt;IUnityContainer &lt;/span&gt;container)
    {
        &lt;span style="color:blue;"&gt;this&lt;/span&gt;.container = container;
    }
    &lt;span style="color:blue;"&gt;#region &lt;/span&gt;IBuilderStrategy Members
    &lt;span style="color:blue;"&gt;public void &lt;/span&gt;PostBuildUp(&lt;span style="color:#2b91af;"&gt;IBuilderContext &lt;/span&gt;context)
    {
        &lt;span style="color:#2b91af;"&gt;ICommandBroker &lt;/span&gt;cb = &lt;span style="color:blue;"&gt;this&lt;/span&gt;.container.Resolve&amp;lt;&lt;span style="color:#2b91af;"&gt;ICommandBroker&lt;/span&gt;&amp;gt;();
        cb.ProcessObjectInfo(context.Existing);
    }
    &lt;span style="color:blue;"&gt;public void &lt;/span&gt;PostTearDown(&lt;span style="color:#2b91af;"&gt;IBuilderContext &lt;/span&gt;context) { }
    &lt;span style="color:blue;"&gt;public void &lt;/span&gt;PreBuildUp(&lt;span style="color:#2b91af;"&gt;IBuilderContext &lt;/span&gt;context) { }
    &lt;span style="color:blue;"&gt;public void &lt;/span&gt;PreTearDown(&lt;span style="color:#2b91af;"&gt;IBuilderContext &lt;/span&gt;context) { }
    &lt;span style="color:blue;"&gt;#endregion
&lt;/span&gt;}&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;En el m&amp;eacute;todo PostBuildUp (despu&amp;eacute;s de que ObjectBuilder2 haya construido el objeto) se llama a ProcessObjectInfo del CommandBroker. Este m&amp;eacute;todo hace dos cosas b&amp;aacute;sicas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Se suscribe a todos los eventos declarados en los atributos CommandSource del tipo del objeto&lt;/li&gt;
&lt;li&gt;Guarda delegados a todos los m&amp;eacute;todos decorados con un CommandTarget (guardando el nombre del command asociado a cada delegado).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As&amp;iacute; el CommandBroker se suscribir&amp;aacute; a &lt;em&gt;cualquier&lt;/em&gt; evento que se lance desde &lt;em&gt;cualquier&lt;/em&gt; objeto creado por Unity, que est&amp;eacute; referenciado por un CommandSource. Y en la funci&amp;oacute;n gestora de dicho evento mirar&amp;aacute; en su tabla interna de delegados&amp;nbsp; si hay alguno que pueda responder a dicho evento (bas&amp;aacute;ndose en el nombre del comando).&lt;/p&gt;
&lt;p&gt;Si observais el constructor de la CommandStrategy, vereis que recibe una instancia del propio Unity. Esto es para poder obtener el CommandBroker, puesto que en la extensi&amp;oacute;n lo registr&amp;aacute;bamos como singleton en Unity. Esto puede parecer sorprendente (que desde una estrategia de Unity no se tenga acceso al propio Unity)&amp;hellip; es lo que dec&amp;iacute;a antes que las estrategias se definen a nivel de ObjectBuilder2.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;7. El c&amp;oacute;digo&amp;hellip;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;No comento m&amp;aacute;s el resto del c&amp;oacute;digo, puesto que s&amp;oacute;lo conseguiria liar el post. Para los interesados lo dejo todo en un zip: &lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/etomas.13022998/UnityExtensions.zip"&gt;UnityExtensions.zip&lt;/a&gt;. El c&amp;oacute;digo est&amp;aacute; comentado para que sea f&amp;aacute;cilmente entendible. Destacar que las clases que hacen el trabajo &lt;em&gt;pesado&lt;/em&gt; son CommandTypeDescriptor (que es quien realmente mira todos los [CommandSource] y [CommandTarget], CommandInfo (que mantiene toda la informaci&amp;oacute;n de UN comando) y el propio CommandBroker.&lt;/p&gt;
&lt;p&gt;Como he dicho el c&amp;oacute;digo NO est&amp;aacute; del todo completo, p.ej. si se registra un singleton con RegisterInstance, dicho singleton no participa del sistema de comandos, y luego en ning&amp;uacute;n caso el CommandBroker se &amp;ldquo;desuscribe&amp;rdquo; a ning&amp;uacute;n evento. Tambi&amp;eacute;n para que fuese una implementaci&amp;oacute;n completa del patr&amp;oacute;n CommandPattern, se deber&amp;iacute;a poder (de alguna manera) activar o desactivar comandos. Al desactivar un comando todos los elementos de la UI vinculados a &amp;eacute;l (o sea todos sus [CommandSource]) deber&amp;iacute;an &lt;em&gt;deshabilitarse&lt;/em&gt;&amp;hellip;&lt;/p&gt;
&lt;p&gt;&amp;hellip; pero bueno, todo es meterse! ;-)&lt;/p&gt;
&lt;p&gt;Espero que este post os haya dado una idea del potencial de extender Unity (y tambi&amp;eacute;n del patron Command Pattern&amp;quot;).&lt;/p&gt;
&lt;p&gt;Saludos!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=142737" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/etomas/archive/tags/patrones/default.aspx">patrones</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/unity/default.aspx">unity</category></item><item><title>Unity? Sí gracias, pero no me abraces demasiado…</title><link>http://geeks.ms/blogs/etomas/archive/2009/02/02/unity-s-237-gracias-pero-no-me-abraces-demasiado.aspx</link><pubDate>Mon, 02 Feb 2009 12:07:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:141765</guid><dc:creator>Eduard Tomàs i Avellana</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/etomas/rsscomments.aspx?PostID=141765</wfw:commentRss><comments>http://geeks.ms/blogs/etomas/archive/2009/02/02/unity-s-237-gracias-pero-no-me-abraces-demasiado.aspx#comments</comments><description>&lt;p&gt;No hace mucho, &lt;a href="http://geeks.ms/user/Profile.aspx?UserID=2963"&gt;Jorge Dieguez&lt;/a&gt; escribi&amp;oacute; &lt;a href="http://geeks.ms/blogs/jdieguez/archive/2009/01/25/microsoft-unity-inyecci-243-n-de-dependencias-net.aspx"&gt;un interesante post sobre Unity&lt;/a&gt; y el patr&amp;oacute;n de &lt;a href="http://en.wikipedia.org/wiki/Dependency_injection"&gt;Dependency Injection&lt;/a&gt;. Resumiendo mucho este patr&amp;oacute;n permite eliminar las dependencias de nuestro c&amp;oacute;digo, trasladandolas todas a un s&amp;oacute;lo elemento, que se conoce generalmente como &amp;ldquo;contenedor de DI&amp;rdquo;. Este contenedor es el responsable de devolvernos todas las referencias a clases que nostros precisemos.&lt;/p&gt;
&lt;p&gt;Las ventajas es que tenemos un c&amp;oacute;digo mucho menos acoplado, que por lo tanto es m&amp;aacute;s f&amp;aacute;cil de probar y de mantener.&lt;/p&gt;
&lt;p&gt;Contenedores de DI hay muchos, p.ej. en .NET tenemos a &lt;a href="http://www.codeplex.com/unity"&gt;Unity&lt;/a&gt; (que viene de la mano de la gente de &lt;a href="http://msdn.microsoft.com/en-us/practices/default.aspx"&gt;P&amp;amp;P&lt;/a&gt;) a &lt;a href="http://www.castleproject.org/container/index.html"&gt;Windsor Container&lt;/a&gt; o a &lt;a href="http://www.springframework.net/"&gt;Spring.NET&lt;/a&gt; s&amp;oacute;lo por citar tres ejemplos. Cada uno de ellos (y de los muchos otros que hay) tienen sus caracter&amp;iacute;sticas y peculiaridades y dado que estamos pensando en hacer c&amp;oacute;digo d&amp;eacute;bilmente acoplado&amp;hellip; quiz&amp;aacute; deber&amp;iacute;amos evitar ligarnos a nuestro contenedor DI, porque nunca sabemos cuando nos puede interesar cambiar.&lt;/p&gt;
&lt;p&gt;Cojamos el caso de Unity. Imaginemos el siguiente proyecto super sencillo:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;namespace &lt;/span&gt;UnityTest
{
    &lt;span style="color:blue;"&gt;interface &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;IFoo &lt;/span&gt;{}
    &lt;span style="color:blue;"&gt;class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;FooClass &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;IFoo &lt;/span&gt;{ }
    &lt;span style="color:blue;"&gt;class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Program
    &lt;/span&gt;{
        &lt;span style="color:blue;"&gt;static void &lt;/span&gt;Main(&lt;span style="color:blue;"&gt;string&lt;/span&gt;[] args)
        {
            &lt;span style="color:#2b91af;"&gt;UnityContainer &lt;/span&gt;uc = &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;UnityContainer&lt;/span&gt;();
            uc.RegisterType&amp;lt;&lt;span style="color:#2b91af;"&gt;IFoo&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;FooClass&lt;/span&gt;&amp;gt;();
            &lt;span style="color:#2b91af;"&gt;IFoo &lt;/span&gt;foo = uc.Resolve&amp;lt;&lt;span style="color:#2b91af;"&gt;IFoo&lt;/span&gt;&amp;gt;();
            &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(foo.GetType().FullName);
            &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.ReadLine();
        }
    }
}&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Es una aplicaci&amp;oacute;n de consola, donde se declara una interfaz (IFoo), una clase que la implementa (FooClass) y luego en el m&amp;eacute;todo Main:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Se crea una instancia de Unity &lt;/li&gt;
&lt;li&gt;Se registra el mapping entre IFoo y FooClass &lt;/li&gt;
&lt;li&gt;Se obtiene una instancia de IFoo. &lt;/li&gt;
&lt;li&gt;Miramos el tipo de la referencia obtenida &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Como os podeis suponer lo que este programa muestra por pantalla es: &lt;span style="font-size:x-small;font-family:Courier New;"&gt;UnityTest.FooClass&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Unity nos devuelve una instancia de FooClass cada vez que le pedimos una instancia de IFoo, porque as&amp;iacute; lo especifica el mapping creado con RegisterType.&lt;/p&gt;
&lt;p&gt;Hasta ahora todo perfecto: nuestra interfaz IFoo y nuestra clase FooClass no estan ligadas a Unity en ning&amp;uacute;n modo&amp;hellip; vamos a ver como se nos pueden &lt;em&gt;torcer&lt;/em&gt; las cosas&amp;hellip;&lt;/p&gt;
&lt;p&gt;Modificamos la clase FooClass para que tenga dos constructores:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;FooClass &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;IFoo 
&lt;/span&gt;{
    &lt;span style="color:blue;"&gt;public &lt;/span&gt;FooClass() 
    { 
        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;FooClass::Default ctor&amp;quot;&lt;/span&gt;); 
    }
    &lt;span style="color:blue;"&gt;public &lt;/span&gt;FooClass(&lt;span style="color:#2b91af;"&gt;BarClass &lt;/span&gt;bar) 
    { 
        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;FooClass::Bar ctor&amp;quot;&lt;/span&gt;); 
    }
}&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;El resto del c&amp;oacute;digo es igual que antes, con la excepci&amp;oacute;n de que nos aparece una clase nueva (BarClass) que da igual (puede ser vac&amp;iacute;a, no nos afecta). La pregunta es obvia: &amp;iquest;que constructor usar&amp;aacute; Unity para construir un objeto FooClass?&lt;/p&gt;
&lt;p&gt;La respuesta es: el que tenga el mayor n&amp;uacute;mero de par&amp;aacute;metros (&amp;iquest;la raz&amp;oacute;n? Quien sabe&amp;hellip;). Unity utilizar&amp;aacute; el constructor con mayor n&amp;uacute;mero de par&amp;aacute;metros e inyectar&amp;aacute; todos los par&amp;aacute;metros (llamando internamente al m&amp;eacute;todo Resolve) a dicho constructor. &amp;iexcl;Eh, un momento! Esto est&amp;aacute; muy bien pero&amp;hellip; nosotros no hemos definido ning&amp;uacute;n mapping para BarClass en Unity&amp;hellip; &amp;iquest;No deber&amp;iacute;a quejarse? Pues no: El m&amp;eacute;todo Resolve&amp;lt;T&amp;gt; de Unity es capaz de crear cualquier clase para que lo no haya un mapping definido, siempre y cuando T sea una clase, no una interfaz.&lt;/p&gt;
&lt;p&gt;Si alguien se pregunta que pasar&amp;iacute;a si FooClass tuviese dos constructores con un par&amp;aacute;metro, entonces Unity se quejar&amp;aacute; con una excepci&amp;oacute;n parecida a: &lt;em&gt;The type FooClass has multiple constructors of length 1. Unable to disambiguate&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Supongamos que queremos que Unity use un constructor en concreto (bien sea porque tenemos varios constructores con mayor n&amp;uacute;mero de par&amp;aacute;metros o bien porque queremos usar alguno en concreto). En este caso, una soluci&amp;oacute;n es aplicar el atributo InjectionConstructor al constructor que queramos que use Unity:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:blue;"&gt;class &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;FooClass &lt;/span&gt;: &lt;span style="color:#2b91af;"&gt;IFoo 
&lt;/span&gt;{
    [&lt;span style="color:#2b91af;"&gt;InjectionConstructor&lt;/span&gt;]
    &lt;span style="color:blue;"&gt;public &lt;/span&gt;FooClass() 
    { 
        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;FooClass::Default ctor&amp;quot;&lt;/span&gt;); 
    }
    &lt;span style="color:blue;"&gt;public &lt;/span&gt;FooClass(&lt;span style="color:#2b91af;"&gt;BarClass &lt;/span&gt;bar) 
    { 
        &lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;FooClass::Bar ctor&amp;quot;&lt;/span&gt;); 
    }
}&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Bueno&amp;hellip; esto funciona correctamente, pero &lt;strong&gt;en este momento hemos creado una dependencia entre FooClass y Unity&lt;/strong&gt;. Si algluna vez nos cambiamos a cualquier otro conenedor de DI, no podemos esperar que entienda el atributo InjectionConstructor, ya que &amp;eacute;ste, obviamente, es propio de Unity. As&amp;iacute; que ahora nuestro c&amp;oacute;digo est&amp;aacute; acoplado a Unity&amp;hellip; lo cual no es la soluci&amp;oacute;n ideal (en algunos casos).&lt;/p&gt;
&lt;p&gt;Por suerte existe una soluci&amp;oacute;n que nos permite que nuestra clase FooClass no tenga dependencias contra Unity: cuando especificamos el mapping podemos indicarle que constructor utilizar. Para ello podemos usar el m&amp;eacute;todo Configure de Unity:&lt;/p&gt;
&lt;pre class="code"&gt;uc.RegisterType&amp;lt;&lt;span style="color:#2b91af;"&gt;IFoo&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;FooClass&lt;/span&gt;&amp;gt;().Configure&amp;lt;&lt;span style="color:#2b91af;"&gt;InjectedMembers&lt;/span&gt;&amp;gt;().
    ConfigureInjectionFor&amp;lt;&lt;span style="color:#2b91af;"&gt;FooClass&lt;/span&gt;&amp;gt;(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;InjectionConstructor&lt;/span&gt;());&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Aqu&amp;iacute; estamos registrando el mapping entre IFoo y FooClass, y configuramos los miembros inyectados para el tipo FooClass para que use el constructor sin par&amp;aacute;metros. Si quisieramos usar el constructor con un par&amp;aacute;metro BarClass:&lt;/p&gt;
&lt;pre class="code"&gt;uc.RegisterType&amp;lt;&lt;span style="color:#2b91af;"&gt;IFoo&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;FooClass&lt;/span&gt;&amp;gt;().Configure&amp;lt;&lt;span style="color:#2b91af;"&gt;InjectedMembers&lt;/span&gt;&amp;gt;().
    ConfigureInjectionFor&amp;lt;&lt;span style="color:#2b91af;"&gt;FooClass&lt;/span&gt;&amp;gt;(
    &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;InjectionConstructor&lt;/span&gt;(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;BarClass&lt;/span&gt;()));&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Con esto Unity cada vez que deba crear un FooClass, usar&amp;aacute; el constructor que acepta un par&amp;aacute;metro BarClass y lo invocar&amp;aacute; con una instancia de BarClass.&amp;nbsp; Unity usar&amp;aacute; siempre la misma instancia de BarClass para todos los FooClass que cree. Es decir, si tenemos:&lt;/p&gt;
&lt;pre class="code"&gt;&lt;span style="color:#2b91af;"&gt;IFoo &lt;/span&gt;foo = uc.Resolve&amp;lt;&lt;span style="color:#2b91af;"&gt;IFoo&lt;/span&gt;&amp;gt;();
&lt;span style="color:#2b91af;"&gt;IFoo &lt;/span&gt;foo2 = uc.Resolve&amp;lt;&lt;span style="color:#2b91af;"&gt;IFoo&lt;/span&gt;&amp;gt;();&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Tanto foo como foo2 ser&amp;aacute;n creados con el constructor que acepta un BarClass pero el BarClass que ambos reciban ser&amp;aacute; el mismo. Incluso aunque no creemos ning&amp;uacute;n objeto FooClass, el objeto BarClass s&amp;iacute; que se crea.&lt;/p&gt;
&lt;p&gt;Si queremos que Unity cree cada vez un BarClass para cada FooClass, entonces podemos utilizar el siguiente c&amp;oacute;digo:&lt;/p&gt;
&lt;pre class="code"&gt;uc.RegisterType&amp;lt;&lt;span style="color:#2b91af;"&gt;IFoo&lt;/span&gt;, &lt;span style="color:#2b91af;"&gt;FooClass&lt;/span&gt;&amp;gt;().Configure&amp;lt;&lt;span style="color:#2b91af;"&gt;InjectedMembers&lt;/span&gt;&amp;gt;().
    ConfigureInjectionFor&amp;lt;&lt;span style="color:#2b91af;"&gt;FooClass&lt;/span&gt;&amp;gt;(
    &lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;InjectionConstructor&lt;/span&gt;(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;BarClass&lt;/span&gt;)));&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;En este caso, Unity crear&amp;aacute; un BarClass nuevo cada vez que deba crear un FooClass&amp;hellip; Bueno, esto no es estrictamente cierto: Realmente Unity cada vez llamar&amp;aacute; a su m&amp;eacute;todo Resolve&amp;lt;BarClass&amp;gt;, cada vez que deba obtener un BarClass para llamar al constructor de FooClass. Si no tenemos mapping definido, Resolve&amp;lt;BarClass&amp;gt; crea un BarClass nuevo cada vez. Pero, si definiesemos el siguiente mapping:&lt;/p&gt;
&lt;pre class="code"&gt;uc.RegisterInstance&amp;lt;&lt;span style="color:#2b91af;"&gt;BarClass&lt;/span&gt;&amp;gt;(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;BarClass&lt;/span&gt;());&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Aqu&amp;iacute; estamos registrando una instancia de BarClass como singleton dentro de Unity. Por lo tanto todas las llamadas a Resolve&amp;lt;BarClass&amp;gt; devolver&amp;aacute;n el mismo objeto&amp;hellip; volvemos a la situaci&amp;oacute;n anterior: todos los constructores de FooClass recibir&amp;aacute;n el mismo BarClass. E igual que antes el BarClass se crea cuando se llama a RegisterInstance, por lo que aunque no creemos ning&amp;uacute;n FooClass, el BarClass s&amp;iacute; que es creado.&lt;/p&gt;
&lt;p&gt;Tenemos una variaci&amp;oacute;n de este caso. Si registramos BarClass como singleton, usando RegisterType:&lt;/p&gt;
&lt;pre class="code"&gt;uc.RegisterType&amp;lt;&lt;span style="color:#2b91af;"&gt;BarClass&lt;/span&gt;&amp;gt;(&lt;span style="color:blue;"&gt;new &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;ContainerControlledLifetimeManager&lt;/span&gt;());&lt;/pre&gt;
&lt;p&gt;&lt;a href="http://11011.net/software/vspaste"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ahora BarClass est&amp;aacute; registrado como singleton,&amp;nbsp; pero no se crear&amp;aacute; la primera instancia de BarClass hasta que sea necesario. As&amp;iacute;, cuando creemos el primer FooClass, Unity crear&amp;aacute; el BarClass y lo usar&amp;aacute; como par&amp;aacute;metro del constructor. Para crear el segundo FooClass, Unity usar&amp;aacute; el BarClass previamente creado.&lt;/p&gt;
&lt;p&gt;Pero lo importante es que nuestra clase FooClass no depende para nada de Unity, de forma que podemos reutilizarla en cualquier otro proyecto o bien cambiar de contenedor de DI&amp;hellip; Que s&amp;iacute;, que Unity est&amp;aacute; muy bien pero tampoco es plan de que nos atemos a &amp;eacute;l, no????&lt;/p&gt;
&lt;p&gt;Saludos!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=141765" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/etomas/archive/tags/patrones/default.aspx">patrones</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/IoC/default.aspx">IoC</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/unity/default.aspx">unity</category></item><item><title>IoC o el poder de ceder el control</title><link>http://geeks.ms/blogs/etomas/archive/2008/10/28/ioc-o-el-poder-de-ceder-el-control.aspx</link><pubDate>Tue, 28 Oct 2008 10:09:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:109560</guid><dc:creator>Eduard Tomàs i Avellana</dc:creator><slash:comments>14</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/etomas/rsscomments.aspx?PostID=109560</wfw:commentRss><comments>http://geeks.ms/blogs/etomas/archive/2008/10/28/ioc-o-el-poder-de-ceder-el-control.aspx#comments</comments><description>&lt;p&gt;Hablando con colegas de profesión, me he dado cuenta de que muchos de ellos no terminan de comprender el patrón IoC o las ventajas que su uso comporta… Así que sin ánimo de sentar cátedra he decidido escribir este post, por si le sirve a alguien… &lt;span style="font-family:Wingdings;"&gt;J&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;IoC, que corresponde a las siglas de Inversion Of Control, agrupa a varios patrones que tienen en común que el flujo de ejecución del programa se invierte respecto a los métodos de programación tradicionales (&lt;a href="http://es.wikipedia.org/wiki/Inversi%C3%B3n_de_Control"&gt;wikipedia dixit&lt;/a&gt;). Generalmente el programador especifica las acciones (métodos) que se van llamando, pero en IoC lo que se especifican son las respuestas a determinados eventos o sucesos, dejando en manos de un elemento externo todas las acciones de control necesarias cuando lleguen estos sucesos.
&lt;/p&gt;&lt;p&gt;Un claro ejemplo de IoC se encuentra en el modelo de eventos de Windows Forms. Cuando vinculamos una función gestora a un evento (p.ej. el Click de un Button), estamos definiendo la respuesta a un determinado evento y nos despreocupamos cuando se llamará a nuestra función gestora. Es decir, cedemos el control del flujo al framework para que sea él que llame cuando sea necesario a nuestro método.
&lt;/p&gt;&lt;p&gt;Una de las principales ventajas de usar patrones IoC es que reducimos el acople entre una clase y las clases de las cuales depende, y eso cuando queremos utilizar por ejemplo tests unitarios es muy importante (no seré yo quien hable ahora de las ventajas de TDD cuando ya lo ha hecho Rodrigo (&lt;a href="http://geeks.ms/blogs/rcorral/archive/2006/12/02/beneficios-y-carater-iacute-sticas-de-un-buen-test-unitario.aspx"&gt;http://geeks.ms/blogs/rcorral/archive/2006/12/02/beneficios-y-carater-iacute-sticas-de-un-buen-test-unitario.aspx&lt;/a&gt;)). De los distintos patrones IoC me interesa comentar específicamente dos: Service Locator y cómo podemos usarlo en .NET. Para más adelante dejo Dependency Injection, otra forma de IoC que también es extremadamente útil.
&lt;/p&gt;&lt;p&gt; Id a la nevera, coged una &lt;a href="http://www.volldamm.es/"&gt;Voll-Damm&lt;/a&gt; o cualquier otra cervecilla y sentaos que este post es un poco largo… &lt;span style="font-family:Wingdings;"&gt;J&lt;/span&gt;
	&lt;/p&gt;&lt;h3&gt;Service Locator
&lt;/h3&gt;&lt;p&gt;El objetivo de Service Locator es reducir las dependencias que tenga una clase. Imaginemos una clase, que depende de otras dos clases (p.ej. ServicioSeguridad y ServicioLogin). Podríamos tener un código tal como:
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span style="color:blue;"&gt;class&lt;/span&gt;
			&lt;span&gt;Client
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;{
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span style="color:blue;"&gt;static&lt;/span&gt;
			&lt;span style="color:blue;"&gt;void&lt;/span&gt; Main(&lt;span style="color:blue;"&gt;string&lt;/span&gt;[] args)
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;{
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left:36pt;"&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;Client&lt;/span&gt;().Run();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span style="color:blue;"&gt;private&lt;/span&gt;
			&lt;span style="color:blue;"&gt;void&lt;/span&gt; Run()
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;{
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left:36pt;"&gt;&lt;span style="color:green;font-family:Courier New;font-size:10pt;"&gt;// En este punto necesitamos objetos de las clases ServicioSeguridad y ServicioLogger
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;
			&lt;span&gt;ServicioSeguridad&lt;/span&gt; ss = &lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;ServicioSeguridad&lt;/span&gt;();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;
			&lt;span&gt;ServicioLogger&lt;/span&gt; sl = &lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;ServicioLogger&lt;/span&gt;();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;
			&lt;span style="color:green;"&gt;//...
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;}&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;En este punto tenemos un fuerte acople entre la clase Client y las clases ServicioSeguridad y ServicioLoggger. Seguiríamos teniendo este mismo acople incluso aunque utilizáramos interfaces porque deberíamos hacer el &amp;quot;new&amp;quot;:
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span&gt;IServicioSeguridad&lt;/span&gt; ss = &lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;ServicioSeguridad&lt;/span&gt;();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span&gt;IServicioLogger&lt;/span&gt; sl = &lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;ServicioLogger&lt;/span&gt;();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Las principales desventajas de esta situación son:
&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Las clases que implementan las dependencias (en nuestro caso ServicioSeguridad y ServicioLogger) deben estar disponibles en tiempo de compilación (no nos basta con tener solo las interfaces).
&lt;/li&gt;&lt;li&gt;El fuerte acople de la clase con sus dependencias dificulta de sobremanera su testing. Si queremos utilizar Mocks para de ServicioSeguridad o ServicioLogger vamos a tener dificultades
&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;El patrón de ServiceLocator soluciona estos dos puntos, sustituyendo las dependencias de la clase Client por dependencias a los interfaces y a un elemento externo, que llamaremos &lt;i&gt;Contenedor&lt;/i&gt; encargado de devolver las referencias que se le piden.
&lt;/p&gt;&lt;p&gt;Cuando la clase necesita un objeto en concreto, lo pide al contenedor:
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span&gt;IServicioSeguridad&lt;/span&gt; ss = container.Resolve&amp;lt;&lt;span&gt;IServicioSeguridad&lt;/span&gt;&amp;gt;(&lt;span&gt;&amp;quot;servicioseguridad&amp;quot;&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span&gt;IServicioLogger&lt;/span&gt; sl = container.Resolve&amp;lt;&lt;span&gt;IServicioLogger&lt;/span&gt;&amp;gt;(&lt;span&gt;&amp;quot;serviciologger&amp;quot;&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;El método Resolve devolvería una referencia del tipo especificado en el parámetro genérico de acuerdo con un identificador. Evidentemente falta alguien que cree el contenedor y que agregue los servicios a él. Es decir, en algún sitio habrá algo como:
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;container = &lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;IoCContainer&lt;/span&gt;();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;container.Add&amp;lt;&lt;span&gt;IServicioSeguridad&lt;/span&gt;, &lt;span&gt;ServicioSeguridad&lt;/span&gt;&amp;gt;(&lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;ServicioSeguridad&lt;/span&gt;(), &lt;span&gt;&amp;quot;servicioseguridad&amp;quot;&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;container.Add&amp;lt;&lt;span&gt;IServicioLogger&lt;/span&gt;, &lt;span&gt;ServicioLogger&lt;/span&gt;&amp;gt;(&lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;ServicioLogger&lt;/span&gt;(), &lt;span&gt;&amp;quot;serviciologger&amp;quot;&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;La gran diferencia es que esto no tiene porque estar en la clase &lt;i&gt;Client&lt;/i&gt;. Simplemente pasándole a la clase Client una referencia al contenedor, eliminamos todas las dependencias de la clase Client con las clases que implementan los servicios. Y donde creamos el contendor? Pues depende… si estamos en nuestra aplicación, lo podemos crear en el método que inicialice la aplicación, pero si queremos probar la clase Client con tests unitarios podemos crear el contenedor en la inicialización del test…. Y lo que es mejor: rellenarlo con Mocks de los servicios!
&lt;/p&gt;&lt;p&gt;Así, nuestro programa podría tener una clase Bootstrapper que crea el contenedor de IoC y lo inicializa con los objetos necesarios:
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span style="color:blue;"&gt;class&lt;/span&gt;
			&lt;span&gt;Bootstrapper
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;{
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span style="color:blue;"&gt;static&lt;/span&gt;
			&lt;span style="color:blue;"&gt;void&lt;/span&gt; Main(&lt;span style="color:blue;"&gt;string&lt;/span&gt;[] args)
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;      {
&lt;/span&gt;&lt;/p&gt;&lt;p style="margin-left:36pt;"&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span&gt;IIoCContainer&lt;/span&gt; container = &lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;IoCContainer&lt;/span&gt;();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;            container.Add&amp;lt;&lt;span&gt;IServicioSeguridad&lt;/span&gt;, &lt;span&gt;ServicioSeguridad&lt;/span&gt;&amp;gt;(&lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;ServicioSeguridad&lt;/span&gt;(), &lt;span&gt;&amp;quot;servicioseguridad&amp;quot;&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;            container.Add&amp;lt;&lt;span&gt;IServicioLogger&lt;/span&gt;, &lt;span&gt;ServicioLogger&lt;/span&gt;&amp;gt;(&lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;ServicioLogger&lt;/span&gt;(), &lt;span&gt;&amp;quot;serviciologger&amp;quot;&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;
			&lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;Client&lt;/span&gt;(container).Run();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;}&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;Pero si queremos usar tests unitarios de la clase Client, podemos cambiar los objetos por Mocks fácilmente:
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;[&lt;span&gt;ClassInitialize&lt;/span&gt;]
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt;
			&lt;span style="color:blue;"&gt;static&lt;/span&gt;
			&lt;span style="color:blue;"&gt;void&lt;/span&gt; Init(&lt;span&gt;TestContext&lt;/span&gt; context)
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;{
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;container = &lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;IoCContainer&lt;/span&gt;();
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;      container.Add&amp;lt;&lt;span&gt;IServicioSeguridad&lt;/span&gt;, &lt;span&gt;ServicioSeguridadMock&lt;/span&gt;&amp;gt;(&lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;ServicioSeguridadMock&lt;/span&gt;(), &lt;span&gt;&amp;quot;servicioseguridad&amp;quot;&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;      container.Add&amp;lt;&lt;span&gt;IServicioLogger&lt;/span&gt;, &lt;span&gt;ServicioLoggerMock&lt;/span&gt;&amp;gt;(&lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;ServicioLoggerMock&lt;/span&gt;(), &lt;span&gt;&amp;quot;serviciologger&amp;quot;&lt;/span&gt;);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;[&lt;span&gt;TestMethod&lt;/span&gt;]
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt;
			&lt;span style="color:blue;"&gt;void&lt;/span&gt; TestMethod1()
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;{
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;&lt;span&gt;Client&lt;/span&gt; c = &lt;span style="color:blue;"&gt;new&lt;/span&gt;
			&lt;span&gt;Client&lt;/span&gt;(container);
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;      c.Run();            &lt;span style="color:green;"&gt;// Este método Run usará los Mocks!
&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:10pt;"&gt;}
&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Fijaos que podemos lanzar tests unitarios sobre la clase Client, sin necesidad alguna de cambiar su código y utilizando Mocks. Además, la clase Client no tiene ninguna dependencia con las implementaciones de los servicios que utiliza, así que no es necesario ni que existan para poder crear la clase Client (sólo necesitamos las interfaces).
&lt;/p&gt;&lt;p&gt;&lt;b&gt;Unity
&lt;/b&gt;&lt;/p&gt;&lt;p&gt;Aunque existen varios contenedores IoC open source para .NET, Microsoft tiene el suyo, también open source, llamado Unity (&lt;a href="http://www.codeplex.com/unity/"&gt;http://www.codeplex.com/unity/&lt;/a&gt;). Unity proporciona soporte para los patrones Service Locator y Dependency Injection.
&lt;/p&gt;&lt;p&gt;Para que veais un poco su uso he dejado un proyecto de herramienta de línea de comandos para listar los ficheros de un directorio (vamos un dir, jejejee…. &lt;span style="font-family:Wingdings;"&gt;J&lt;/span&gt;).
&lt;/p&gt;&lt;p&gt;La solución está dividida en varios proyectos:
&lt;/p&gt;&lt;ol&gt;&lt;li&gt;DemoIoC: Contiene el Bootstrapper, la clase que inicializa el contenedor de Unity, agrega la clase llamada ServicioFicheros y utiliza un objeto Cliente para realizar las acciones de la línea de comandos.
&lt;/li&gt;&lt;li&gt;Cliente: Contiene la implementación de la clase Cliente.
&lt;/li&gt;&lt;li&gt;Interfaces: Contiene las interfaces del servicio (en este caso sólo una)
&lt;/li&gt;&lt;li&gt;Implementations: Contiene las implementaciones del servicio (en este caso sólo una)
&lt;/li&gt;&lt;li&gt;Mocks: Contiene las implementaciones de los Mocks (en este caso sólo una)
&lt;/li&gt;&lt;li&gt;UnitTests: Contiene tests sobre la clase Cliente, usando un Mock del servicio ServicioFicheros.
&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;El ejecutable (proyecto DemoIoC, assembly DemoIoC.exe) es un archivo de línea de comandos que acepta dos parámetros:
&lt;/p&gt;&lt;p&gt;DemoIoC –l para listar todos los ficheros (del directorio actual)
&lt;/p&gt;&lt;p&gt;DemoIoC –e:fichero.ext Indica si el fichero &amp;quot;fichero.ext&amp;quot; existe (en el directorio actual).
&lt;/p&gt;&lt;p&gt;Si lo ejecutáis veréis que NO funciona bien: lista los ficheros correctamente, pero devuelve que un fichero existe cuando no es cierto y viceversa. Si miráis el código de la clase Cliente, encontrareis el error, ya que es obvio, pero lo bueno es que el proyecto UnitTest, testea este método de la clase Cliente, usando un Mock del ServicioFicheros y el UnitTest detecta el error. Observad lo fácil que ha sido sustituir el ServicioFicheros por un Mock sin alterar la clase Cliente, gracias al uso del patrón Service Locator!
&lt;/p&gt;&lt;p&gt;PD: Estooooo... que me he dejado de adjuntar el código de ejemplo... Lo teneis &lt;a href="http://geeks.ms/blogs/etomas/IoC/DemoIoC.zip"&gt;aquí&lt;/a&gt;!!! &lt;br /&gt;&lt;/p&gt;&lt;p&gt;Saludos!!!
&lt;/p&gt;&lt;h3&gt;Referencias
&lt;/h3&gt;&lt;p&gt;Os dejo algunas referencias para su lectura por si os interesa profundizar un poco en el tema tratado:
&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Unity Container (&lt;a href="http://www.codeplex.com/unity/"&gt;http://www.codeplex.com/unity/&lt;/a&gt;)
&lt;/li&gt;&lt;li&gt;Patrón Service Locator (&lt;a href="http://msdn.microsoft.com/en-us/library/cc707905.aspx"&gt;http://msdn.microsoft.com/en-us/library/cc707905.aspx&lt;/a&gt;)
&lt;/li&gt;&lt;li&gt;Inversion of Control (&lt;a href="http://msdn.microsoft.com/en-us/magazine/cc947917.aspx"&gt;http://msdn.microsoft.com/en-us/magazine/cc947917.aspx&lt;/a&gt;)
&lt;/li&gt;&lt;li&gt;Mocks (&lt;a href="http://martinfowler.com/articles/mocksArentStubs.html"&gt;http://martinfowler.com/articles/mocksArentStubs.html&lt;/a&gt;)
&lt;/li&gt;&lt;/ul&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=109560" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/etomas/archive/tags/TDD/default.aspx">TDD</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/patrones/default.aspx">patrones</category><category domain="http://geeks.ms/blogs/etomas/archive/tags/IoC/default.aspx">IoC</category></item></channel></rss>