<?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 : IoC</title><link>http://geeks.ms/blogs/etomas/archive/tags/IoC/default.aspx</link><description>Etiquetas: IoC</description><dc:language /><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><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>Novedades de Unity 2.0</title><link>http://geeks.ms/blogs/etomas/archive/2010/06/02/novedades-de-unity-2-0.aspx</link><pubDate>Wed, 02 Jun 2010 13:02:56 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:177581</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=177581</wfw:commentRss><comments>http://geeks.ms/blogs/etomas/archive/2010/06/02/novedades-de-unity-2-0.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://unity.codeplex.com/" target="_blank"&gt;Unity&lt;/a&gt;, el &lt;a href="http://martinfowler.com/articles/injection.html" target="_blank"&gt;contenedor IoC&lt;/a&gt; de Microsoft, hace algunas semanas que tiene nueva versión: la 2.0. Y viene con algunas novedades interesantes respecto a la versión anterior, que os comento brevemente :)&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Por fin… un único assembly!&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Vale que Unity era poco más que un &lt;em&gt;wrapper&lt;/em&gt; sobre &lt;a href="http://objectbuilder.codeplex.com/" target="_blank"&gt;ObjectBuilder2&lt;/a&gt; pero tampoco era necesario que nos lo recordaran continuamente… ahora ya no tendremos que añadir la referencia a ObjectBuilder2 además de la referencia a Unity cada vez… Ahora existe un solo assembly: Microsoft.Practices.Unity.dll. ¿Un detalle sin apenas importancia? Pues probablemente :)&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Resoluciones deferidas&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Esta funcionalidad nos permite resolver tipos con Unity sin tener una dependencia contra Unity. P.ej. imagina que tenemos Unity configurado 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;IUnityContainer uc = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; UnityContainer();&lt;br /&gt;uc.RegisterType&amp;lt;IA, A&amp;gt;();&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Y tenemos un método que necesita construir un objeto IA a través de Unity… Antes debíamos pasarle el contenedor Unity:&lt;/p&gt;

&lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; OldFoo(IUnityContainer ctr)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#008000;"&gt;// ... Código antes de resolver IA ...&lt;/span&gt;&lt;br /&gt;    IA a = ctr.Resolve&amp;lt;IA&amp;gt;();&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Ahora, con Unity 2.0 podemos obtener un &lt;em&gt;resolvedor&lt;/em&gt; (perdonad por la palabreja) que no es nada más que un delegate que cuando sea invocado llamará a Resolve de Unity. Esto nos permite que la función OldFoo &lt;em&gt;no tenga dependencia alguna contra Unity&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;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; NewFoo(Func&amp;lt;IA&amp;gt; resolver)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#008000;"&gt;// ... Código antes de resolver IA ...&lt;/span&gt;&lt;br /&gt;    IA a = resolver();&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Y la llamada a NewFoo quedaría de la forma:&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;var resolver = uc.Resolve&amp;lt;Func&amp;lt;IA&amp;gt;&amp;gt;();&lt;br /&gt;NewFoo(resolver);&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;De esta manera el método NewFoo no necesita para nada el contenedor Unity :)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Paso de parámetros en Resolve&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Esto permite pasar parámetros a un objeto cuando se llama a su método Resolve.&lt;/p&gt;

&lt;p&gt;Supon que tenemos 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;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; IB { }&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; B : IB&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; B(&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;) { }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Y tenemos un mapping declarado en Unity:&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 uc = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; UnityContainer();&lt;br /&gt;uc.RegisterType&amp;lt;IB, B&amp;gt;();&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Como es de esperar la siguiente llamada falla:&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;IB b = uc.Resolve&amp;lt;IB&amp;gt;();&lt;br /&gt;&lt;span style="color:#008000;"&gt;// Exception is: InvalidOperationException - The type Int32 cannot be constructed.&lt;/span&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Unity se queja, porque cuando va al constructor de la clase B se encuentra que le debe pasar un parámetro de tipo Int32 (int). Pero como no tiene ningún mapeo de int, se queja.&lt;/p&gt;

&lt;p&gt;Para solucionar este caso podemos usar los &lt;em&gt;ResolverOverride&lt;/em&gt;. P.ej. para pasarle el valor 3 al parámetro “value” basta con usar:&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;IB b = uc.Resolve&amp;lt;IB&amp;gt;(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ParameterOverride(&lt;span style="color:#006080;"&gt;&amp;quot;value&amp;quot;&lt;/span&gt;, 3));&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Pero no solo nos sirven para especificar valores de parámetros cuyos tipos no estén registrados en el contenedor, también podemos indicarle valor a un parámetro &lt;em&gt;incluso&lt;/em&gt; en el caso que Unity pudiese proveer un valor para el 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;interface&lt;/span&gt; IA { }&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; A : IA { }&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;interface&lt;/span&gt; IB { IA A { get; } }&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; B : IB&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; IA A { 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; B(IA a)&lt;br /&gt;    {&lt;br /&gt;        A = a;&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 uc = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; UnityContainer();&lt;br /&gt;        uc.RegisterType&amp;lt;IA, A&amp;gt;(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ContainerControlledLifetimeManager());&lt;br /&gt;        uc.RegisterType&amp;lt;IB, B&amp;gt;();&lt;br /&gt;        IA a1 = uc.Resolve&amp;lt;IA&amp;gt;();&lt;br /&gt;        IA a2 = uc.Resolve&amp;lt;IA&amp;gt;();&lt;br /&gt;        IB b = uc.Resolve&amp;lt;IB&amp;gt;();&lt;br /&gt;        IB b2 = uc.Resolve&amp;lt;IB&amp;gt;(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ParameterOverride(&lt;span style="color:#006080;"&gt;&amp;quot;a&amp;quot;&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; A()));&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Dado el siguiente código tenemos que:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;a1 == a2 es &lt;em&gt;true&lt;/em&gt; puesto que IA está registrado como singleton, por lo que todas las llamadas a Resolve&amp;lt;IA&amp;gt; devuelven el mismo valor&lt;/li&gt;

  &lt;li&gt;a1 == b.A es &lt;em&gt;true&lt;/em&gt; por la misma razón de antes: Cuando Unity debe proporcionar un valor IA al constructor de la clase B, utiliza el método Resolve por lo que devuelve el singleton.&lt;/li&gt;

  &lt;li&gt;a1 == b2.A es &lt;em&gt;false&lt;/em&gt; porque aquí aunque Unity puede proporcionar un valor para el parámetro, el valor especificado en el &lt;em&gt;ParameterOverride&lt;/em&gt; tiene preferencia.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Por fin!!! Podemos saber que hay registrado en el contenedor&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Se han añadido métodos para saber todos los registros de mapeos del contenedor y para saber si un mapeo en concreto existe:&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 uc = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; UnityContainer();&lt;br /&gt;uc.RegisterType&amp;lt;IA, A&amp;gt;(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ContainerControlledLifetimeManager());&lt;br /&gt;uc.RegisterType&amp;lt;IB, B&amp;gt;();&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; isTrue = uc.IsRegistered&amp;lt;IA&amp;gt;();&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; isFalse = uc.IsRegistered&amp;lt;IC&amp;gt;();&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; numRegs = uc.Registrations.Count();&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Por cierto, que dado el siguiente código… cuanto vale numRegs?&lt;/p&gt;

&lt;p&gt;Sí habeis dicho &lt;strong&gt;2&lt;/strong&gt;, habéis fallado… recordad que Unity se &lt;em&gt;registra&lt;/em&gt; a si mismo, por lo que realmente numRegs vale 3 (el propio registro de Unity, el de IA y el de IB).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;InjectionFactory&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;InjectionFactory es un mecanismo que permite indicarle a Unity un método (una Func&amp;lt;IUnityContainer, object&amp;gt;, usualmente una lambda expresion) a usar cada vez que deba resolver un objeto especificado. Permite que Unity use factorías nuestras.&lt;/p&gt;

&lt;p&gt;Imagina que tenemos una factoría para crear objetos IA:&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; IFactory&lt;br /&gt;{&lt;br /&gt;    IA GetNewInstance();&lt;br /&gt;}&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Factory : IFactory&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; IA GetNewInstance()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#008000;"&gt;// Hace lo que tenga que hacer nuestra factoria... &lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; A();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Y ahora deseamos usar Unity para la creación de objetos IA. Pues podemos realizar el siguiente Register:&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 uc = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; UnityContainer();&lt;br /&gt;uc.RegisterType&amp;lt;IFactory, Factory&amp;gt;(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ContainerControlledLifetimeManager());&lt;br /&gt;uc.RegisterType&amp;lt;IA&amp;gt;(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; InjectionFactory&lt;br /&gt;    (x =&amp;gt; x.Resolve&amp;lt;IFactory&amp;gt;().GetNewInstance()));&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;En la última línea le estamos indicando a Unity que cada vez que alguien haga un Resolve&amp;lt;IA&amp;gt; ejecute el delegate que le indicamos (en este caso que obtenga una IFactory y llame al método GetNewInstance).&lt;/p&gt;

&lt;p&gt;Esto si lo combinamos con lo de las resoluciones diferidas es realmente interesante.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Y estas serían las novedades, a mi juicio, más interesantes de Unity 2 (que no son todas… si las queréis saber todas, &lt;a href="http://unity.codeplex.com/wikipage?title=Unity2ChangeLog&amp;amp;referringTitle=Unity2#changes" target="_blank"&gt;las tenéis aquí&lt;/a&gt;!).&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=177581" width="1" height="1"&gt;</description><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 (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>Lifetime Managers en Unity o ¿como sé que eso que me das es un singleton?</title><link>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</link><pubDate>Mon, 26 Oct 2009 16:31:51 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:158947</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=158947</wfw:commentRss><comments>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#comments</comments><description>&lt;p&gt;Los que leais habitualmente mi blog (¡muchas gracias!) habreis visto que tengo &lt;a href="http://geeks.ms/blogs/etomas/archive/tags/unity/default.aspx"&gt;varias entradas sobre unity&lt;/a&gt; el contenedor IoC de la gente de patterns &amp;amp; practices. En ellas he ido comentando varios aspectos más o menos avanzados del contenedor y de los patrones IoC associados.&lt;/p&gt;  &lt;p&gt;En este post quiero hablaros un poco de los “lifetime managers”, objetos que le indican a Unity si cuando debe resolver un objeto debe crear uno nuevo o bien devolver uno existente.&lt;/p&gt;  &lt;p&gt;Resumiendo &lt;strong&gt;mucho&lt;/strong&gt; podemos afirmar que:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Con RegisterType&amp;lt;IA, A&amp;gt;() lo que hacemos es registrar un mapeo de la interfaz IA a la clase A: cada vez que pidamos un objeto IA, usando Resolve&amp;lt;IA&amp;gt;(), el contenedor nos devolverá &lt;em&gt;un nuevo&lt;/em&gt; objeto A.&lt;/li&gt;    &lt;li&gt;Con RegisterInstance&amp;lt;IA&amp;gt;(IA instance) lo que hacemos es registrar un singleton de la interfaz IA. Cada vez que pidamos un objeto IA, el contenedor nos devolverá &lt;em&gt;el mismo&lt;/em&gt; objeto: el que hemos pasado como parámetro a RegisterInstance.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;La realidad es, como casi siempre, un poco más compleja. Unity no distingue solamente los casos “crear un objeto cada vez” o “devolver siempre el mismo objeto”, sino que la decisión de si se debe crear un objeto nuevo o no se deriva en otra clase: el lifetime manager. De serie con Unity vienen 3 lifetime managers distintos:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;TransientLifetimeManager: Cada vez que tengamos que devolver un objeto crearemos &lt;em&gt;uno nuevo.&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;ContainerControlledLifetimeManager: Devolveremos siempre el mismo objeto (singleton).&lt;/li&gt;    &lt;li&gt;PerThreadLifetimeManager: Devolveremos siempre el mismo objeto, pero crearemos un objeto para cada thread (singleton a nivel de thread).&lt;/li&gt;    &lt;li&gt;ExternallyControlledLifetimeManager: Cada vez que tengamos que devolver un objeto devolveremos el mismo, si este sigue vivo (es decir el garbage collector no lo ha “recogido”). Obviamente Unity no mantiene una referencia al objeto sino una WeakReference, ya que en caso contrario el objeto estaría vivo “para siempre” dentro de Unity.&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Tomemos la siguiente interfaz IA, y la clase A que la implementa:&lt;/p&gt;  &lt;div style="border-bottom:silver 1px solid;text-align:left;border-left:silver 1px solid;padding-bottom:4px;line-height:12pt;background-color:#f4f4f4;margin:20px 0px 10px;padding-left:4px;width:97.5%;padding-right:4px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;max-height:200px;font-size:8pt;overflow:auto;border-top:silver 1px solid;cursor:text;border-right:silver 1px solid;padding-top:4px;" id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style:none;text-align:left;padding-bottom:0px;line-height:12pt;border-right-style:none;background-color:#f4f4f4;margin:0em;padding-left:0px;width:100%;padding-right:0px;font-family:&amp;#39;Courier New&amp;#39;, courier, monospace;direction:ltr;border-top-style:none;color:black;font-size:8pt;border-left-style:none;overflow:visible;padding-top:0px;" id="codeSnippet"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;interface&lt;/span&gt; IA&lt;br /&gt;{&lt;br /&gt;    Guid Id {get;}&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; A : IA&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; Guid Id {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; A()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Id = Guid.NewGuid();&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Cada objeto A creado tendrá su propio Id único.&lt;/p&gt;

&lt;p&gt;Ahora miremos el siguiente 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;IUnityContainer container = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; UnityContainer();&lt;br /&gt;&lt;br /&gt;container.RegisterType&amp;lt;IA, A&amp;gt;(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ContainerControlledLifetimeManager());&lt;br /&gt;IA a1 = container.Resolve&amp;lt;IA&amp;gt;();&lt;br /&gt;IA a2 = container.Resolve&amp;lt;IA&amp;gt;();&lt;br /&gt;Console.WriteLine(&lt;span style="color:#006080;"&gt;&amp;quot;a1: &amp;quot;&lt;/span&gt; + a1.Id.ToString());&lt;br /&gt;Console.WriteLine(&lt;span style="color:#006080;"&gt;&amp;quot;a2: &amp;quot;&lt;/span&gt; + a2.Id.ToString());&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Si ejecutáis el siguiente código observareis que el ID es el mismo: Unity nos ha devuelto el mismo objeto para las dos llamadas a container.Resolve&amp;lt;IA&amp;gt;(). Esto ha sido porque hemos especificado un ContainerControlledLifetimeManager como parámetro a la llamada RegisterType.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Si ahora modificamos el ContainerControlledLifetimeManager por un ExternallyControlledLifetimeManager el resultado es el mismo: ambos Resolve reciben el mismo objeto.&lt;/p&gt;

&lt;p&gt;Ahora bien, si forzamos una recolección del Garbage Collector:&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;IA, A&amp;gt;(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ExternallyControlledLifetimeManager());&lt;br /&gt;IA a1 = container.Resolve&amp;lt;IA&amp;gt;();&lt;br /&gt;Console.WriteLine(&lt;span style="color:#006080;"&gt;&amp;quot;a1: &amp;quot;&lt;/span&gt; + a1.Id.ToString());&lt;br /&gt;a1 = &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;      &lt;span style="color:#008000;"&gt;// Importante! Si no es null, el GC no puede recojer el objeto!&lt;/span&gt;&lt;br /&gt;GC.Collect();&lt;br /&gt;IA a2 = container.Resolve&amp;lt;IA&amp;gt;();&lt;br /&gt;Console.WriteLine(&lt;span style="color:#006080;"&gt;&amp;quot;a2: &amp;quot;&lt;/span&gt; + a2.Id.ToString());&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Ahora podemos observar como la segunda llamada a Resolve ha obtenido un objeto distinto al de la primera llamada (ya que el Garbage Collector ha eliminado el primer objeto).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Crear nuestros propios lifetime managers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ahora que hemos visto que la realidad es un poco más divertida, la siguiente pregunta es: podemos crear nuestros propios lifetime managers? Y la respuesta es sí!&lt;/p&gt;

&lt;p&gt;Para ello simplemente debemos crearnos una clase que herede LifetimeManager y que implemente los métodos:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;SetValue: Que invoca Unity cuando ha creado el objeto. En este método podemos guardarnos el objeto creado.&lt;/li&gt;

  &lt;li&gt;GetValue: Donde devolvemos el objeto o bien null, para que Unity cree uno de nuevo (y luego nos invoque SetValue).&lt;/li&gt;

  &lt;li&gt;RemoveValue: Cuando se elimina un objeto&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Una nota importante sobre RemoveValue: Unity nunca llama a este método, está ahí para que nosotros podamos eliminar objetos de Unity, siempre y cuando tengamos acceso al Lifetime manager.&lt;/p&gt;

&lt;p&gt;Veamos un posible ejemplo de un Lifetime manager:&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; CustomLifetimeManager : LifetimeManager&lt;br /&gt;  {&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;[] values;&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; idx = 0;&lt;br /&gt;&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; CustomLifetimeManager(&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; instances)&lt;br /&gt;      {&lt;br /&gt;          values = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt;[instances];&lt;br /&gt;          idx = -1;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; SetValue(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; newValue)&lt;br /&gt;      {&lt;br /&gt;          values[idx] = newValue;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; GetValue()&lt;br /&gt;      {&lt;br /&gt;          idx = (idx + 1) % values.Length;&lt;br /&gt;          &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt; = values[idx];&lt;br /&gt;          &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;value&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;override&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; RemoveValue()&lt;br /&gt;      {&lt;br /&gt;          &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt; = values[idx];&lt;br /&gt;          values[idx] = &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;br /&gt;          idx = (idx + 1) % values.Length;&lt;br /&gt;          &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;is&lt;/span&gt; IDisposable)&lt;br /&gt;          {&lt;br /&gt;              ((IDisposable)&lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;).Dispose();&lt;br /&gt;          }&lt;br /&gt;      }&lt;br /&gt;  }&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;El código se comenta casi solo, no? Este lifetime manager guarda x instancias del objeto, eso significa que Unity nos devolverá hasta x objetos distintos, y luego empezará a repetirlos.&lt;/p&gt;

&lt;p&gt;P.ej. dado el siguiente 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;IUnityContainer container = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; UnityContainer();&lt;br /&gt;CustomLifetimeManager lft = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; CustomLifetimeManager(3);&lt;br /&gt;&lt;br /&gt;container.RegisterType&amp;lt;IA, A&amp;gt;(lft);&lt;br /&gt;&lt;br /&gt;IA a1 = container.Resolve&amp;lt;IA&amp;gt;();&lt;br /&gt;IA a2 = container.Resolve&amp;lt;IA&amp;gt;();&lt;br /&gt;IA a3 = container.Resolve&amp;lt;IA&amp;gt;();&lt;br /&gt;&lt;span style="color:#008000;"&gt;// Repes!&lt;/span&gt;&lt;br /&gt;IA a4 = container.Resolve&amp;lt;IA&amp;gt;();&lt;br /&gt;IA a5 = container.Resolve&amp;lt;IA&amp;gt;();&lt;br /&gt;IA a6 = container.Resolve&amp;lt;IA&amp;gt;();&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Hemos configurado nuestro CustomLifetimeManager para que nos de hasta tres objetos distintos. Los tres primeros Resolve recibirán cada uno un objeto nuevo distinto… pero luego el cuarto resolve recibirá de nuevo el primer objeto, el quinto recibirá el segundo y así sucesivamente: hemos creado un &lt;em&gt;pool&lt;/em&gt; de objetos.&lt;/p&gt;

&lt;p&gt;Como veis es realmente fácil, crearos vuestros propios lifetime managers, lo que os permite personalizar al máximo cuando Unity debe crear un objeto nuevo o devolver uno ya existente!&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=158947" width="1" height="1"&gt;</description><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>ASP.NET MVC Custom Action Filters y IoC</title><link>http://geeks.ms/blogs/etomas/archive/2009/10/02/asp-net-mvc-custom-action-filters-y-ioc.aspx</link><pubDate>Fri, 02 Oct 2009 12:48:12 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:157230</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=157230</wfw:commentRss><comments>http://geeks.ms/blogs/etomas/archive/2009/10/02/asp-net-mvc-custom-action-filters-y-ioc.aspx#comments</comments><description>&lt;p&gt;Que es una buena práctica usar un contenedor IoC hoy en día es algo que está más que aceptado… la gente que montó ASP.NET MVC lo tiene muy claro y por eso ha creado un framework, que aunque no usa ningún contenedor IoC por defecto, se puede &lt;em&gt;extender&lt;/em&gt; para usar uno… P.ej. si quieres que tus controladores sean creados a través de un contenedor IoC (y &lt;em&gt;deberías querrerlo&lt;/em&gt;) solo debes crearte una factoría de controladores e indicar a ASP.NET MVC que use esta factoría en lugar de la que viene por defecto.&lt;/p&gt;  &lt;p&gt;El siguiente código muestra una factoría de controladores que usa Unity:&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;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#008000;"&gt;/// ControllerFactory que utilitza Unity per crear els controladors.&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:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; UnityControllerFactory : DefaultControllerFactory&lt;br /&gt;{&lt;br /&gt;    IUnityContainer container;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; UnityControllerFactory(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;protected&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; IController GetControllerInstance (Type controllerType)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (controllerType == &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;)&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ArgumentNullException(&lt;span style="color:#006080;"&gt;&amp;quot;controllerType&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!&lt;span style="color:#0000ff;"&gt;typeof&lt;/span&gt;(IController).IsAssignableFrom(controllerType))&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ArgumentException(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Format(&lt;br /&gt;                &lt;span style="color:#006080;"&gt;&amp;quot;El tipus {0} NO és un controller.&amp;quot;&lt;/span&gt;, controllerType.Name),&lt;br /&gt;                &lt;span style="color:#006080;"&gt;&amp;quot;controllerType&amp;quot;&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(controllerType) &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; IController;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Indicar a ASP.NET MVC que use dicha factoría es tan fácil como meter lo siguiente en algún punto del Application_Start del 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;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;IControllerFactory factory = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; UnityControllerFactory(container);&lt;br /&gt;ControllerBuilder.Current.SetControllerFactory(factory);&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Listos! Ahora nuestros controladores serán creados por Unity…&lt;/p&gt;

&lt;p&gt;Lamentablemente incluso un framework tan extensible como ASP.NET MVC a veces no es tan extensible como nos gustaría… Una de las capacidades más interesantes de ASP.NET MVC son los llamados filtros. Un filtro es una forma de inyectar código que se ejecuta &lt;em&gt;antes y/o después&lt;/em&gt; de que se ejecute el código de una acción de un controlador. El propio framework viene con varios filtros, como p.ej. &lt;em&gt;Authorize&lt;/em&gt; que impide ejecutar una acción de un controlador si el usuario no está autenticado. El uso de filtros es uno de los mecanismos más interesantes de ASP.NET MVC y permite la aplicación de técnicas de la programación orientada a aspectos.&lt;/p&gt;

&lt;p&gt;Seguro que si pensáis un poco os vienen a la cabeza muchas posibles ideas: P.ej. hacer un logging de todas las acciones, habilitar políticas de caching, gestionar los errores redirigiendo a una o varias páginas de error… Muchas de estas ideas (y más) ya vienen implementadas en el framework, pero lo bueno es que podemos crearnos &lt;strong&gt;nuestros&lt;/strong&gt; propios filtros para crear nuestras propias tareas.&lt;/p&gt;

&lt;p&gt;Los filtros se aplican a las acciones mediante atributos, p.ej. en el caso del filtro para autorización, decoraríamos las acciones:&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;[Authorize(Roles=&lt;span style="color:#006080;"&gt;&amp;quot;Admin&amp;quot;&lt;/span&gt;)]&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; ActionResult Create()&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; View();&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;En este caso la acción sólo se ejecutará si el usuario está autenticado y además tiene el rol “Admin”.&lt;/p&gt;

&lt;p&gt;Crear un filtro propio no es especialmente complejo, basta derivar de FilterAttribute y adicionalmente implementar uno o varios de los siguientes interfaces:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;IAuthorizationFilter: Si debemos autorizar el uso o no de la acción en función de determinados parámetros&lt;/li&gt;

  &lt;li&gt;IActionFilter: Para ejecutar lógica de negocio antes y después de la propia acción (el caso más común)&lt;/li&gt;

  &lt;li&gt;IResultFilter: Para ejecutar lógica de negocio antes y después de la ejecución del resultado de la acción.&lt;/li&gt;

  &lt;li&gt;IExcepcionFilter: Para gestionar errores.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Se pueden implementar uno o varios de esos interfaces. La clase FilterAttribute deriva de Attribute por lo que para aplicar nuestro propio filtro, basta con decorar las acciones.&lt;/p&gt;

&lt;p&gt;Bueno… a lo que íbamos que me pierdo: si usáis un contenedor IoC para crear vuestros controladores seguramente desearéis usar el mismo contenedor IoC para instanciar vuestros filtros… Desgraciadamente esto no es tan directo como “crear una factoría de filtros” y registrarla, así que requiere un poco de más de trabajo. Os cuento dos técnicas para usar un contenedor IoC (en mi caso Unity) para vuestros filtros propios.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Técnica 1: Tener el contenedor como variable de aplicación&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Esta es la más sencilla de todas: en global.asax, guardais el contenedor IoC en alguna variable de aplicación y luego en el filtro la recuperáis (por suerte tenemos acceso al HttpContext). En mi caso estoy implementando un IAuthorizationFilter, y en el código del método OnAuthorization tengo 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;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;void&lt;/span&gt; OnAuthorization(AuthorizationContext filterContext)&lt;br /&gt;{&lt;br /&gt;    IUnityContainer container =  filterContext.HttpContext.Application[&lt;span style="color:#006080;"&gt;&amp;quot;container&amp;quot;&lt;/span&gt;] &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; IUnityContainer;&lt;br /&gt;    IGlobalSettings settings =  container.Resolve&amp;lt;IGlobalSettings&amp;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;En este caso IGlobalSettings es el objeto registrado a Unity. Podemos acceder a Unity, porque lo tengo guardado en una variable de aplicación (en global.asax es donde lo guardo), y puedo acceder a las variables de aplicación a través del filterContext, que recibo como parámetro.&lt;/p&gt;

&lt;p&gt;Todas las interfaces de los filtros reciben el filterContext &lt;strong&gt;excepto&lt;/strong&gt; IActionFilter que recibe un ControllerContext, pero desde el ControllerContext también se puede acceder a las variables de aplicación.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Técnica 2: Usar un Custom ActionInvoker&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Esta técnica consiste en extender el framework de ASP.NET MVC por uno de sus muchos puntos, y nos vamos a crear un custom ActionInvoker. El ActionInvoker es el encargado de “invocar” las acciones de los controladores, y por tanto es donde se crean los filtros asociadas a dichas acciones. Luego podemos indicar a los controladores que se creen que usen nuestro propio ActionInvoker.&lt;/p&gt;

&lt;p&gt;En este caso nuestra propoa ActionInvoker lo que debe hacer es inyectar los valores a los filtros. Nunca podremos crear los filtros usando Unity ya que los filtros son atributos, y por tanto son “creados automáticamente” por el CLR. El código de nuestra ActionInvoker puede ser tal y como 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;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; UnityActionInvoker : ControllerActionInvoker&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; UnityActionInvoker(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:#0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; FilterInfo GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)&lt;br /&gt;    {&lt;br /&gt;        var filters = &lt;span style="color:#0000ff;"&gt;base&lt;/span&gt;.GetFilters(controllerContext, actionDescriptor);&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (var filter &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; filters.ActionFilters)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!(filter &lt;span style="color:#0000ff;"&gt;is&lt;/span&gt; IController)) container.BuildUp(filter.GetType(), filter);&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (var filter &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; filters.AuthorizationFilters)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!(filter &lt;span style="color:#0000ff;"&gt;is&lt;/span&gt; IController)) container.BuildUp(filter.GetType(), filter);&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (var filter &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; filters.ExceptionFilters)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!(filter &lt;span style="color:#0000ff;"&gt;is&lt;/span&gt; IController)) container.BuildUp(filter.GetType(), filter);&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;foreach&lt;/span&gt; (var filter &lt;span style="color:#0000ff;"&gt;in&lt;/span&gt; filters.ResultFilters)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!(filter &lt;span style="color:#0000ff;"&gt;is&lt;/span&gt; IController)) container.BuildUp(filter.GetType(), filter);&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; filters;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;El código es bastante simple: el método que nos interesa se llama “GetFilters”. Este método es el encargado de obtener los filtros asociados a la acción de un controlador. Los filtros se devuelven en un objeto FilterInfo, que básicamente son cuatro colecciones para los distintos tipos de filtros que tenemos. Nuestro código se limita a recorrer dichas colecciones y por cada filtro ejecutar el método &lt;em&gt;BuildUp&lt;/em&gt; de Unity que inyecta las dependencias. En este caso obviamente no podemos utilizar inyección de dependencias en el constructor (puesto que el objeto ya está creado), pero si podemos utilizar inyección de propiedades.&lt;/p&gt;

&lt;p&gt;El código de mi filtro ahora queda tal y como se ve:&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;[Dependency]&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; IGlobalSettings Settings { get; set; }&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; OnAuthorization(AuthorizationContext filterContext)&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;La propiedad Settings es la que Unity inyectará a mi filtro cuando se llame al método BuildUp.&lt;/p&gt;

&lt;p&gt;Los más observadores habréis visto que en mi Custom ActionInvoker, cuando recorro el FilterInfo miro que el filtro no sea de tipo IController: los controladores &lt;strong&gt;son&lt;/strong&gt; filtros de ASP.NET MVC, y además la clase Controller implementa los cuatro interfaces posibles de filtro (por lo que aparecerá UNA vez en cada colección de FilterInfo).&lt;/p&gt;

&lt;p&gt;Finalmente, nos queda indicar a cada controlador que use nuestra clase UnityActionInvoker. Para ello basta asignar la propiedad ActionInvoker de cada controlador. Esta propiedad es de la clase Controller (no del interfaz IController). Lo podemos hacer de tres maneras:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;En el constructor de cada controlador (no muy recomendable por tedioso)&lt;/li&gt;

  &lt;li&gt;Derivar todos nuestros controladores de una clase base y hacerlo en el constructor de la clase base&lt;/li&gt;

  &lt;li&gt;Hacerlo en nuestra factoría de controladores (en el método GetControllerInstance):&lt;/li&gt;
&lt;/ol&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;protected&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;override&lt;/span&gt; IController GetControllerInstance (Type controllerType)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#008000;"&gt;// Código anterior...&lt;/span&gt;&lt;br /&gt;    controller.ActionInvoker = container.Resolve&amp;lt;UnityActionInvoker&amp;gt;();&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; controller;&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Y listos! Ahora sí: nuestros filtros ya pueden usar propiedades inyectadas por Unity! :)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Y ya por curiosidad…&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Igual alguno de vosotros se pregunta como era mi filtro: en mi caso estoy desarrollando una aplicación web que es (o será cuando los dioses quieran) un juego. Algunas de las acciones sólo pueden ser ejecutadas cuando el juego está en marcha (con independencia de si el usuario está autenticado o no). Podría poner un if() en cada una de las acciones pero… cuando veais que debeis poner un if() idéntico en muchas acciones, considerad el uso de un filtro.&lt;/p&gt;

&lt;p&gt;En mi caso el filtro lo que hace es redirigir a una página de error en caso de que el juego no esté en marcha y la acción requiera que el juego si que lo esté (o viceversa, ciertas acciones de administración sólo se deben poder realizar con el juego &lt;em&gt;parado&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;El código del filtro es tal y como 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;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; GameStartedAttribute : FilterAttribute, IAuthorizationFilter&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; &lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; started;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; GameStartedAttribute()&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.started = &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; GameStartedAttribute(&lt;span style="color:#0000ff;"&gt;bool&lt;/span&gt; started)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.started = started;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    [Dependency]&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; IGlobalSettings Settings { get; set; }&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; OnAuthorization(AuthorizationContext filterContext)&lt;br /&gt;    {&lt;br /&gt;        IUnityContainer container =  filterContext.HttpContext.Application[&lt;span style="color:#006080;"&gt;&amp;quot;container&amp;quot;&lt;/span&gt;] &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; IUnityContainer;&lt;br /&gt;        IGlobalSettings settings =  container.Resolve&amp;lt;IGlobalSettings&amp;gt;();&lt;br /&gt;        &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (settings.GameStarted != &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.started)&lt;br /&gt;        {&lt;br /&gt;            filterContext.Result = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; ViewResult()&lt;br /&gt;            {&lt;br /&gt;                ViewName = settings.GameStarted ? &lt;span style="color:#006080;"&gt;&amp;quot;GameStarted&amp;quot;&lt;/span&gt; : &lt;span style="color:#006080;"&gt;&amp;quot;GameNotStarted&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;En este caso es un IAuthorizationFilter, ya que en cierta manera estamos autorizando peticiones (acciones) no en función del usuario, sinó en función del juego. En el método OnAuthorization se redirige al usuario a las dos páginas de error si el estado del juego no es el pedido, y en caso contrario no se hace nada (y se ejecuta la acción).&lt;/p&gt;

&lt;p&gt;La forma de aplicar el filtro es decorando las acciones con el atributo [GameStarted]:&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;// El juego debe estar en marcha para ejecutar esta acción. Si el juego está&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#008000;"&gt;// parado el usuario será redirigido a una página explicativa.&lt;/span&gt;&lt;br /&gt;[GameStarted(&lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;)]&lt;br /&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; ActionResult Index()&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; View();&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Como siempre espero que el post os haya resultado útil para daros cuenta de lo extensible que resulta ser ASP.NET MVC ;-)&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=157230" width="1" height="1"&gt;</description><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>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>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>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>