<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/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>Angel "Java" Lopez : Inversion of Control</title><link>http://msmvps.com/blogs/lopez/archive/tags/Inversion+of+Control/default.aspx</link><description>Tags: Inversion of Control</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>IoC y DI: Hello, world con Spring Framework</title><link>http://msmvps.com/blogs/lopez/archive/2010/08/13/ioc-y-di-hello-world-con-spring-framework.aspx</link><pubDate>Fri, 13 Aug 2010 10:37:51 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1775896</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1775896</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2010/08/13/ioc-y-di-hello-world-con-spring-framework.aspx#comments</comments><description>&lt;p&gt;Ya vimos algo de Inversion of Control y Dependency Injection en:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2010/08/12/definiendo-inversion-of-control-and-dependency-injection.aspx" target="_blank"&gt;Definiendo Inversion of Control y Dependency Injection&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2010/07/28/introducci-243-n-a-ioc-y-di-otro-ejemplo-web.aspx"&gt;Introducción a IoC y DI: Otro ejemplo web&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2010/07/21/introducci-243-n-a-ioc-y-di-un-ejemplo-web.aspx"&gt;Introducción a IoC y DI: Un ejemplo web&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2010/07/21/introducci-243-n-a-ioc-y-di-un-ejemplo-web.aspx"&gt;Introducción a IoC y DI: Hello, world flexible&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;material producido dentro del &lt;a href="http://msmvps.com/blogs/lopez/archive/2010/03/26/hogwarts_2D00_project.aspx"&gt;Proyecto Hogwarts&lt;/a&gt;. En el post donde definía IoC y DI, mencioné la existencia de contenedores de IoC: utilitarios que facilitan el “armado” de los objetos y sus relaciones. En el primer post de la serie, describí el ejemplo más simple posible. Veamos ahora de poder levantar el mismo ejemplo apelando a un contendor de IoC.&lt;/p&gt;  &lt;p&gt;Uno de los más conocidos, uno de los primeros, es el &lt;a href="http://www.springframework.net/"&gt;Spring Framework de .NET&lt;/a&gt; (port de la &lt;a href="http://www.springsource.com/"&gt;implementación inicial en Java&lt;/a&gt;). Veamos la estructura del ejemplo (que se puede bajar de &lt;a href="http://cid-9f903f3d6db0c176.office.live.com/self.aspx/Examples/Hogwarts/HelloWorldSpringExample.zip" target="_blank"&gt;HelloWorldSpringExample.zip&lt;/a&gt;).&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/ioc09.png" alt="" /&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Vemos que refiere a Spring.Core, una librería que les dejo incluida en el ejemplo. Seguimos teniendo nuestras interfaces IMessageProcessor, IMessageProvider, y nuestras clases concretas MessageProcessor y MessageProvider. Pero nuestro programa ahora ejecuta:&lt;/p&gt;  &lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,courier,monospace;font-size:12px;"&gt;    &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; Program
    {
        &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)
        {
            IApplicationContext context = ContextRegistry.GetContext();
            IMessageProcessor processor = (IMessageProcessor)context.GetObject(&amp;quot;&lt;span style="color:#8b0000;"&gt;processor&lt;/span&gt;&amp;quot;);
            processor.Process();
        }
    }
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Spring tendrá a su cargo crear los objetos, a medida que los pedimos. El ContextRegistry es parte de Spring. Levanta información de los objetos que queremos trabajar. Para poder usarlo, tenemos que incluir los namespaces:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; Spring.Context.Support;
&lt;span style="color:#0000ff;"&gt;using&lt;/span&gt; Spring.Context;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;En su forma más sencilla, como la de arriba, toma sus datos de la configuración:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;?&lt;/span&gt;xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; &lt;span style="color:#0000ff;"&gt;?&amp;gt;&lt;/span&gt;
&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;configuration&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;configSections&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;sectionGroup&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;name&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;&amp;quot;spring&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
      &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;section&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;name&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;&amp;quot;context&amp;quot;&lt;/span&gt; 
      &lt;span style="color:#ff0000;"&gt;type&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;&amp;quot;Spring.Context.Support.ContextHandler, Spring.Core&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;sectionGroup&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;configSections&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;spring&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;context&lt;/span&gt; 
      &lt;span style="color:#ff0000;"&gt;type&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;&amp;quot;Spring.Context.Support.XmlApplicationContext, Spring.Core&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
      &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;resource&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;uri&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;&amp;quot;file://SpringConfig.xml&amp;quot;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span style="color:#008000;"&gt;&amp;lt;!--&amp;lt;resource uri=&amp;quot;assembly://HelloWorld1/HelloWorld1/EmbeddedSpringConfig.xml&amp;quot;/&amp;gt;--&amp;gt;&lt;/span&gt;
    &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;context&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;spring&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;configuration&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Se definió un nuevo sectionGroup llamado spring, que es leído por la librería. Ahí se puede poner la configuración de nuestro ejemplo, pero elegí referir a un archivo aparte, así podemos cambiarlo sin tocar la configuración general de la aplicación. Vean que dejé comentado otra forma: incluir ese archivo de configuración como recurso embebido. El SpringConfig.xml está marcado en el proyecto como Copy to Output Directory Always.&lt;/p&gt;

&lt;p&gt;El archivo SpringConfig.xml tiene:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;?&lt;/span&gt;xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot; &lt;span style="color:#0000ff;"&gt;?&amp;gt;&lt;/span&gt;
&lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;objects&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;xmlns&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;&amp;#39;http://www.springframework.net&amp;#39;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;object&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;id&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;&amp;#39;provider&amp;#39;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;type&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;&amp;#39;HelloWorldSpringExample.MessageProvider&amp;#39;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;property&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;name&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;&amp;#39;Message&amp;#39;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;value&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;&amp;#39;Hello, World&amp;#39;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;property&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;object&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;object&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;id&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;&amp;#39;processor&amp;#39;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;type&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;&amp;#39;HelloWorldSpringExample.MessageProcessor&amp;#39;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color:#0000ff;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#800000;"&gt;property&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;name&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;&amp;#39;Provider&amp;#39;&lt;/span&gt; &lt;span style="color:#ff0000;"&gt;ref&lt;/span&gt;=&lt;span style="color:#0000ff;"&gt;&amp;#39;provider&amp;#39;&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;object&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color:#0000ff;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:#800000;"&gt;objects&lt;/span&gt;&lt;span style="color:#0000ff;"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Podemos definir cada objeto, darle:&lt;/p&gt;

&lt;p&gt;- un id (nombre)&lt;/p&gt;

&lt;p&gt;- un tipo (qué tipo concreto creamos)&lt;/p&gt;

&lt;p&gt;- argumentos para su constructor&lt;/p&gt;

&lt;p&gt;- valores para sus propiedades&lt;/p&gt;

&lt;p&gt;Cuando especificamos un valor podemos poner value=”Hello, world” un valor en concreto, o podemos referir a otro objeto conocido y creable por Spring, usando ref=”provider”.&lt;/p&gt;

&lt;p&gt;Entonces, cada objeto lo completamos inyectándole otros objetos via propiedades o argumentos en el constructor. &lt;/p&gt;

&lt;p&gt;Notemos la forma en que la propiedad Provider del MessageProcessor es &amp;quot;inyectada&amp;quot;: referenciando (atributo ref) a otro objeto que Spring conoce cómo crear.&lt;/p&gt;

&lt;p&gt;De esta forma, se pueden levantar grafos de objetos complejos, pidiendo posiblemente uno desde nuestro programa. En este ejemplo, pedimos el objeto con id=processor. Automáticamente, Spring creó el objeto con id=provider, y le inyectó el mensaje que contiene.&lt;/p&gt;

&lt;p&gt;Tenemos que ver otro ejemplo de Spring, tener algún ejemplo web, y usar otros contenedores, como Ninject o StructureMap. Y cuando tengamos más experiencia, volveremos a ver qué se consiguió con esto, y qué características tienen los contenedores IoC.&lt;/p&gt;

&lt;p&gt;Nos leemos!&lt;/p&gt;

&lt;p&gt;Angel “Java” Lopez 
  &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1775896" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Hogwarts/default.aspx">Hogwarts</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Inversion+of+Control/default.aspx">Inversion of Control</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Dependency+Injection/default.aspx">Dependency Injection</category></item><item><title>Definiendo Inversion of Control and Dependency Injection</title><link>http://msmvps.com/blogs/lopez/archive/2010/08/12/definiendo-inversion-of-control-and-dependency-injection.aspx</link><pubDate>Thu, 12 Aug 2010 08:50:21 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1775817</guid><dc:creator>lopez</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1775817</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2010/08/12/definiendo-inversion-of-control-and-dependency-injection.aspx#comments</comments><description>&lt;p&gt;Después de algunos ejemplos de código, dentro del &lt;a href="http://msmvps.com/blogs/lopez/archive/2010/03/26/hogwarts_2D00_project.aspx"&gt;Proyecto Hogwarts&lt;/a&gt;:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2010/07/28/introducci-243-n-a-ioc-y-di-otro-ejemplo-web.aspx" target="_blank"&gt;Introducción a IoC y DI: Otro ejemplo web&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2010/07/21/introducci-243-n-a-ioc-y-di-un-ejemplo-web.aspx"&gt;Introducción a IoC y DI: Un ejemplo web&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2010/07/21/introducci-243-n-a-ioc-y-di-un-ejemplo-web.aspx"&gt;Introducción a IoC y DI: Hello, world flexible&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;veamos de definir los términos Inversion of Control (Inversión de Control) y Dependency Injection (Inyección de Dependencias). &lt;/p&gt;  &lt;p&gt;Recordemos lo que vimos en los ejemplos: los objetos no funcionan solos, forman un grafo de objetos. Algunos objetos colaboran con otros. Se dice entonces que los objetos consumidores tienen dependencia de los objetos que consumen como ayudantes. En una aplicación real, el mantener las dependencias puede irse complicando, debido a la cantidad de clases y responsabilidades. También, puede que querramos modificar las implementaciones. Vimos que nos conviene ir definiendo interfaces, y referirse a ellas, para no ligar los objetos consumidores a implementaciones concretas. &lt;/p&gt;  &lt;p&gt;Inversion of Control refiere, entonces, a que el objeto consumidor no crea los objectos ayudantes, de los que depende. No se le adosa esa responsabilidad. Como vimos en los ejemplos, en esos objetos desaparece el &amp;quot;new&amp;quot; de los objetos ayudantes. &lt;/p&gt;  &lt;p&gt;Dependency Injection se refiere a una forma de implementar IoC: el objeto consumidor recibe sus dependencias en propiedades o en argumentos de constructor. &lt;/p&gt;  &lt;p&gt;Recordemos el ejemplo de servicio consumiendo repositorio, gráficamente:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/ioc10.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;El código de nuestro servicio no tenía new (con lo que tiene Inversion of Control). Pero bien podría haber pedido expresamente a otro que le diera el objeto, como en:&lt;/p&gt;  &lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; CustomerService
{
    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; ICustomerRepository repository;
    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; CustomerService()
    {
        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.repository = Registry.GetInstance&amp;lt;ICustomerRepository&amp;gt;();
    }
    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; IEnumerable&amp;lt;Customer&amp;gt; GetCustomers()
    {
        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; repository.GetAll();
    }
}
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;En este caso, sería simplemente Inversion of Control: alguien, la clase Registry, tendría la responsabilidad de ubicar o crear la instancia a usar. Pero CustomerService pide esa resolución explícitamente. 
  &lt;br /&gt;En cambio, el código de nuestro ejemplo era:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; CustomerService
{
    &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; ICustomerRepository repository;
    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; CustomerService(ICustomerRepository repository)
    {
        &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.repository = repository;
    }
    &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; IEnumerable&amp;lt;Customer&amp;gt; GetCustomers()
    {
        &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; repository.GetAll();
    }
}
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Acá apareció Dependency Injection: CustomerService ni siquiera pide el repositorio, alguien de afuera se lo da. Tenemos que estudiar que podemos usar librerías llamadas contenedores de IoC que nos facilitan la inyección automática de esas dependencias.&lt;/p&gt;

&lt;p&gt;No necesariamente se inyecta un solo objeto: otras clases más complejas podrán necesitar de más objetos inyectados. Tenemos que investigar formas de inyectarle esas dependencias. Por ahora, lo vimos “manualmente”: vamos a ver que hay librerías llamadas IoC Containers, contenedores de Inversion of Control, que nos pueden ayudar a armar el grafo que necesitamos en un contexto (en producción, en pruebas TDD, etc…)&lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;Artículos en inglés para consultar con más detalles:&lt;/p&gt;

&lt;p&gt;
  &lt;br /&gt;&lt;a href="http://www.martinfowler.com/articles/injection.html"&gt;Inversion of Control Containers and the Dependency Injection pattern&lt;/a&gt; (Martin Fowler) 

  &lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/aa973811.aspx"&gt;Inversion of Control and Dependency Injection: Working with Windsor Container&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mis enlaces sobre el tema:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://delicious.com/ajlopez/ioc"&gt;http://delicious.com/ajlopez/ioc&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://delicious.com/ajlopez/di"&gt;http://delicious.com/ajlopez/di&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nos leemos!&lt;/p&gt;

&lt;p&gt;Angel “Java” Lopez 
  &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1775817" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Hogwarts/default.aspx">Hogwarts</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Inversion+of+Control/default.aspx">Inversion of Control</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Dependency+Injection/default.aspx">Dependency Injection</category></item><item><title>Introducción a IoC y DI: otro ejemplo web</title><link>http://msmvps.com/blogs/lopez/archive/2010/07/28/introducci-243-n-a-ioc-y-di-otro-ejemplo-web.aspx</link><pubDate>Wed, 28 Jul 2010 10:23:50 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1774867</guid><dc:creator>lopez</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1774867</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2010/07/28/introducci-243-n-a-ioc-y-di-otro-ejemplo-web.aspx#comments</comments><description>&lt;p&gt;Sigamos explorando Inversion of Control y Dependency Injection, dentro del &lt;a href="http://msmvps.com/blogs/lopez/archive/2010/03/26/hogwarts_2D00_project.aspx" target="_blank"&gt;Proyecto Hogwarts&lt;/a&gt;. Anteriores posts del tema:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2010/07/21/introducci-243-n-a-ioc-y-di-un-ejemplo-web.aspx" target="_blank"&gt;Introducción a IoC y DI: Un ejemplo web&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2010/07/21/introducci-243-n-a-ioc-y-di-un-ejemplo-web.aspx" target="_blank"&gt;Introducción a IoC y DI: Hello, world flexible&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Simplemente para ver otro ejemplo sencillo de programación con interfaces, veamos de agregar un objeto presenter en un ejemplo web. La forma de llenar la página con datos (dar datos a la vista) y la forma de atender comandos del usuario (un botón de aceptar en un formulario para grabar lo ingresado), lo separamos del &amp;quot;code behind&amp;quot; y le asignamos esa responsabilidad a un objeto Presenter:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/ioc07.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Notemos que la vista que va a consumir no es una clase concreta, sino una interfaz. Eso nos va a permitir cambiar la vista, o probar a nuestro objeto presenter sin necesidad de darle una página web para operar, sino algún otro objeto más adecuado para nuestras pruebas.    &lt;br /&gt;El código de este ejemplo se puede bajar de &lt;a href="http://cid-9f903f3d6db0c176.office.live.com/self.aspx/Examples/Hogwarts/PresenterExample.zip" target="_blank"&gt;PresenterExample.zip&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Esta vez, la solución tiene dos proyectos de librería de clases, y una aplicación web:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/ioc08.png" alt="" /&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;El primer proyecto se basa en nuestro anterior ejemplo: contiene el servicio, ayudado por repositorios.&lt;/p&gt;  &lt;p&gt;El segundo proyecto define la interfaz que tiene que cumplir todas las vistas de lista de Customers, ICustomerListView:&lt;/p&gt;  &lt;pre&gt;&lt;pre style="margin:0em;width:100%;font-family:consolas,courier,monospace;font-size:12px;"&gt;&lt;span&gt;namespace&lt;/span&gt; Customers.Presenters {  &lt;span&gt;public&lt;/span&gt; &lt;span&gt;interface&lt;/span&gt; ICustomerListView
   {
      IEnumerable&amp;lt;Customer&amp;gt; Customers { &lt;span&gt;set&lt;/span&gt;; }
   }
}
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;El Presenter consume tanto a la vista como al servicio:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="margin:0em;width:100%;font-family:consolas,courier,monospace;font-size:12px;"&gt; &lt;span&gt;public&lt;/span&gt; &lt;span&gt;class&lt;/span&gt; CustomerPresenter  {
    &lt;span&gt;private&lt;/span&gt; ICustomerService service;
    &lt;span&gt;private&lt;/span&gt; ICustomerListView view;
    &lt;span&gt;public&lt;/span&gt; CustomerPresenter(ICustomerService service, ICustomerListView view)
    {
       &lt;span&gt;this&lt;/span&gt;.service = service;
       &lt;span&gt;this&lt;/span&gt;.view = view;
    }
    &lt;span&gt;public&lt;/span&gt; &lt;span&gt;void&lt;/span&gt; Initialize()
    {
      &lt;span&gt;this&lt;/span&gt;.view.Customers = &lt;span&gt;this&lt;/span&gt;.service.GetCustomers();
    }
 }
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Vean que el servicio también lo ve como una interfaz. Finalmente, el código de la página arma todos los objetos y se &amp;quot;conecta&amp;quot; con el Presenter para que éste la maneje. En nuestro ejemplo, sólo para llenar sus datos:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,courier,monospace;font-size:12px;"&gt;  &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; partial &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; _Default : System.Web.UI.Page, ICustomerListView
    {
        &lt;span style="color:#0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Page_Load(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, EventArgs e)
        {
            &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (!&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.IsPostBack)
            {
                CustomerPresenter presenter = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; CustomerPresenter(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; CustomerService(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; InMemoryCustomerRepository()), &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;);
                presenter.Initialize();
            }
        }
        &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; IEnumerable&amp;lt;Customer&amp;gt; Customers
        {
            &lt;span style="color:#0000ff;"&gt;set&lt;/span&gt;
            {
                &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.grdCustomers.DataSource = &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;;
                &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.grdCustomers.DataBind();
            }
        }
    }
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Este ejemplo es un paso más hacia el tema de esta serie de post: Inversion of Control y Dependency Injection, términos que tenemos que definir. Pero, como en el post anterior, hay algo para mejorar: en el código de la página decidimos qué objetos concretos conectamos en un grafo de objetos colaboradores. Lo que quisiéramos mejorar es la definición de esos objetos concretos: tratar de no tenerlo de alguna forma fijo en el código, sino tener alguna otra manera de instanciarlos y de cambiar cuáles son las clases concretas a usar.&lt;/p&gt;

&lt;p&gt;Este material será incluido en el curso online del &lt;a href="http://blog.salias.com.ar/2010/05/presentando-southworks-professional.html"&gt;Southworks Professional Improvement Program&lt;/a&gt; en &lt;a href="http://pip.southworks.net/"&gt;http://pip.southworks.net/&lt;/a&gt; (pueden ir ahí para ir explorando el curso de TDD ya publicado).&lt;/p&gt;

&lt;p&gt;Nos leemos!&lt;/p&gt;

&lt;p&gt;Angel “Java” Lopez 
  &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1774867" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Hogwarts/default.aspx">Hogwarts</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Inversion+of+Control/default.aspx">Inversion of Control</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Dependency+Injection/default.aspx">Dependency Injection</category></item><item><title>Introducción a IoC y DI: Un ejemplo web</title><link>http://msmvps.com/blogs/lopez/archive/2010/07/21/introducci-243-n-a-ioc-y-di-un-ejemplo-web.aspx</link><pubDate>Wed, 21 Jul 2010 10:20:39 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1774425</guid><dc:creator>lopez</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1774425</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2010/07/21/introducci-243-n-a-ioc-y-di-un-ejemplo-web.aspx#comments</comments><description>&lt;p&gt;Sigo posteando material de lo que se está produciendo en el &lt;a href="http://msmvps.com/blogs/lopez/archive/2010/03/26/hogwarts_2D00_project.aspx" target="_blank"&gt;Proyecto Hogwarts&lt;/a&gt;. Esta vez, sobre el tema de Inversion of Control y Dependency Injection. Dentro de poco, estará disponible un sitio en línea con un curso de TDD, y otros en construcción. En el anterior post:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2010/07/13/introducci-243-n-a-ioc-y-di-hello-world-flexible.aspx" target="_blank"&gt;Introducción a IoC, DI: Hello, world flexible&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;había planteado un ejemplo simple, veamos alguno apenas más complejo. Y veamos de plantearla con interfaces. &lt;/p&gt;  &lt;p&gt;Lo que vimos en ese ejemplo es que: &lt;/p&gt;  &lt;p&gt;- Un objeto A puede necesitar la ayuda de otro objeto B, pero conociendo la interface, sin ligarse a una clase en concreto &lt;/p&gt;  &lt;p&gt;- Al objeto A alguien le provee el objeto B &lt;/p&gt;  &lt;p&gt;Lo que vamos explorar ahora, es un ejemplo donde al objeto A le damos alguna vez un objeto B1, y otras veces el objeto B2. Para que no sea sólo una aplicación de consola, veamos de levantar el alcance, y hagamos un ejemplo web.&lt;/p&gt;  &lt;p&gt;Sea una simple aplicación web, donde tenemos una página para presionar dos enlaces para leer y mostrar los clientes:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/ioc03.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;La idea es tener DOS implementaciones de una interface que se haga responsable de implementar un repositorio de clientes (digamos, una lista de clientes). Si presionamos en el primer enlace, se usará un repositorio en memoria:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/ioc04.png" alt="" /&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Si presionamos en el segundo enlace, usaremos el repositorio de base de datos:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/ioc05.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Pueden bajarse el ejemplo desde mi Skydrive &lt;a href="http://cid-9f903f3d6db0c176.office.live.com/self.aspx/Examples/Hogwarts/CustomersExample.zip" target="_blank"&gt;CustomersExample.zip&lt;/a&gt;. Contiene una solución .NET y los scripts para crear la base de datos en SQL Server.&lt;/p&gt;  &lt;p&gt;En este ejemplo, vamos a usar un servicio que se ayudará de un repositorio para conseguir los objetos que necesita la presentación. Veamos cómo se implementó.&lt;/p&gt;  &lt;p&gt;Tenemos entonces, un servicio que necesita consumir un repositorio. Como en el ejemplo de Hello, world, el objeto consumidor no referencia a una clase concreta, sino a una interfaz:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/ioc06.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Esa interfaz está definida como:&lt;/p&gt;  &lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;namespace&lt;/span&gt; Customers
{
 &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;interface&lt;/span&gt; ICustomerRepository
 {
 Customer GetById(&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; id);
 &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Insert(Customer customer);
 &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Update(Customer customer);
 &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Delete(Customer customer);
 IQueryable&amp;lt;Customer&amp;gt; GetAll();
 }
}
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Luego tenemos dos implementaciones de esta interfaz:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/ioc02.png" alt="" /&gt; &lt;/p&gt;

&lt;p&gt;Una es la implementación del repositorio en memoria, parte del código:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,courier,monospace;font-size:12px;"&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; InMemoryCustomerRepository : ICustomerRepository
 {
 &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; IList&amp;lt;Customer&amp;gt; customers = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; List&amp;lt;Customer&amp;gt;();
 &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; InMemoryCustomerRepository()
 {
 &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; k = 1; k &amp;lt;= 10; k++)
 {
 customers.Add(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Customer()
 {
 Id = k,
 Name = &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Format(&amp;quot;&lt;span style="color:#8b0000;"&gt;Customer {0}&lt;/span&gt;&amp;quot;, k),
 Address = &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Format(&amp;quot;&lt;span style="color:#8b0000;"&gt;Address {0}&lt;/span&gt;&amp;quot;, k),
 Notes = &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;.Format(&amp;quot;&lt;span style="color:#8b0000;"&gt;Notes {0}&lt;/span&gt;&amp;quot;, k)
 });
 }
 }
&lt;span style="color:#008000;"&gt;//....&lt;/span&gt;
 }
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;La otra implementación de la interfaz accede a una base de datos, código parcial:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,courier,monospace;font-size:12px;"&gt; &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;class&lt;/span&gt; DatabaseCustomerRepository : ICustomerRepository
 {
 &lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; connectionstring;
 &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; DatabaseCustomerRepository(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; connectionstring)
 {
 &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.connectionstring = connectionstring;
 }
 &lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; Customer GetById(&lt;span style="color:#0000ff;"&gt;int&lt;/span&gt; id)
 {
 SqlConnection conn = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SqlConnection(&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.connectionstring);
 SqlCommand cmd = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SqlCommand(&amp;quot;&lt;span style="color:#8b0000;"&gt;select Id, Name, Address, Notes from Customer where Id = @Id&lt;/span&gt;&amp;quot;, conn);
 cmd.Parameters.Add(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; SqlParameter(&amp;quot;&lt;span style="color:#8b0000;"&gt;@Id&lt;/span&gt;&amp;quot;, id));
 conn.Open();
 SqlDataReader reader = cmd.ExecuteReader();
 Customer customer = &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;
 &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (reader.Read())
 customer = &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.GetCustomer(reader);
 reader.Close();
 conn.Close();
 &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; customer;
 }
&lt;span style="color:#808080;"&gt;///...&lt;/span&gt;
 }&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Lo que se usó en este ejemplo es que al crear el objeto servicio le pasamos en los argumentos del constructor cuál implementación de repositorio queremos usar. Así, en la acción de ver por memoria, el código es:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,courier,monospace;font-size:12px;"&gt;&lt;span style="color:#0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; lnkMemory_Click(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, EventArgs e)
 {
 CustomerService service = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; CustomerService(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; InMemoryCustomerRepository());
 &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.grdCustomers.DataSource = service.GetCustomers();
 &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.grdCustomers.DataBind();
 }
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;La otra opción es por base de datos:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,courier,monospace;font-size:12px;"&gt; &lt;span style="color:#0000ff;"&gt;protected&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; lnkData_Click(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, EventArgs e)
 {
 CustomerService service = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; CustomerService(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; DatabaseCustomerRepository(&amp;quot;&lt;span style="color:#8b0000;"&gt;server=.\SQLEXPRESS;database=Customers;integrated security=true&lt;/span&gt;&amp;quot;));
 &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.grdCustomers.DataSource = service.GetCustomers();
 &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.grdCustomers.DataBind();
 }
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Notemos que al servicio le &amp;quot;inyectamos&amp;quot; su ayudante, esta vez usando un parámetro de su constructor (en el ejemplo Hello World, habiamos inyectado usando propiedades). &lt;/p&gt;

&lt;p&gt;Esto nos muestra: &lt;/p&gt;

&lt;p&gt;- La capacidad de abstraer lo que necesitamos (la interfaz de repositorio) de cómo lo implementamos 
  &lt;br /&gt;- Nos permite cambiar la implementación y que todo siga funcionando igual &lt;/p&gt;

&lt;p&gt;Acá usamos las DOS implementaciones al mismo tiempo. Pero es más común usar solo una. &lt;/p&gt;

&lt;p&gt;Podríamos haber codificado el acceso a los clientes en el propio servicio. Pero lo separamos para: &lt;/p&gt;

&lt;p&gt;- Poder mejorar el servicio (p.ej., en temas de seguridad) separando esas otras funcionalidades de la más simple de recuperación de clientes. &lt;/p&gt;

&lt;p&gt;- Poder cambiar el ayudante, sin necesidad de cambiar el servicio y sus consumidores. &lt;/p&gt;

&lt;p&gt;Hasta podemos ir armando una aplicación de demostración, usando durante semanas la implementación del repositorio en memoria. Mientras, en un desarrollo ágil, vamos iterando, mejorando nuestro dominio, SIN tener una base de datos por debajo. El cliente final va viendo nuestro avance, y solamente cuando tenemos algo más definido, vamos definiendo la base de datos subyacente y operando sobre ella. &lt;/p&gt;

&lt;p&gt;También, este &amp;quot;approach&amp;quot; nos permite cambiar la implementación de la base de datos. Ahora, la implementación va contra SQL Server, pero si mañana necesitamos ir contra Oracle, cambiamos la implementación, y ni servicio y otros se enteran de ese cambio. &lt;/p&gt;

&lt;p&gt;Y por último, veremos, más adelante en otro curso (Mocks con TDD), que podemos usar implementaciones de repositorios que no vayan contra la base, para alivianar nuestros tests del servicio. &lt;/p&gt;

&lt;p&gt;Y todo, por haber programado contra la interfaz, y segregado responsabilidades. &lt;/p&gt;

&lt;p&gt;Tenemos que avanzar en un sentido: no queremos tener que cambiar el código de creación del servicio, para que una vez use una implementación del repositorio (en memoria) y otra vez use una distinta (en base de datos). Quisiéramos que el cambiar esa relación NO IMPLIQUE tener que cambiar el código. Esa es la idea que subyace en lo que tenemos que definir en los próximos post de este tema: qué es Inversion of Control, qué es Dependency Injection, y contenedores de IoC.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Nos leemos!&lt;/p&gt;

&lt;p&gt;Angel “Java” Lopez 
  &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1774425" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Hogwarts/default.aspx">Hogwarts</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Inversion+of+Control/default.aspx">Inversion of Control</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Dependency+Injection/default.aspx">Dependency Injection</category></item><item><title>Introducción a IoC y DI: Hello, world, flexible</title><link>http://msmvps.com/blogs/lopez/archive/2010/07/13/introducci-243-n-a-ioc-y-di-hello-world-flexible.aspx</link><pubDate>Tue, 13 Jul 2010 22:29:23 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1773878</guid><dc:creator>lopez</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1773878</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2010/07/13/introducci-243-n-a-ioc-y-di-hello-world-flexible.aspx#comments</comments><description>&lt;p&gt;Dentro del &lt;a href="http://msmvps.com/blogs/lopez/archive/2010/03/26/hogwarts_2D00_project.aspx" target="_blank"&gt;Proyecto Hogwarts&lt;/a&gt;, estamos produciendo material para un curso de Inversion of Control y Dependency Injection, que quedará en línea (además de preparar alguna charla o taller presencial). No voy a explicar todavía los términos, sino que quisiera seguir otro camino: tomando la aplicación más simple, ir viendo de flexibilizarla, hasta llegar en algún momento a usar IoC y DI (siglas de los términos en inglés para Inversión de Control e Inyección de Dependencias).&lt;/p&gt;  &lt;p&gt;¿Cuál es la aplicación más simple? Tomemos un clásico “Hello, world” en C# (espero publicar más adelante una serie de versiones en Java, que culmine con el uso de Spring Framework, como hago en mis cursos sobre el tema):&lt;/p&gt;  &lt;pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,courier,monospace;"&gt; &lt;span&gt;class&lt;/span&gt; Program
 {
 &lt;span&gt;static&lt;/span&gt; &lt;span&gt;void&lt;/span&gt; Main(&lt;span&gt;string&lt;/span&gt;[] args)
 {
 Console.WriteLine(&amp;quot;&lt;span&gt;Hello, world&lt;/span&gt;&amp;quot;);
 }
 }
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;¿Qué podemos querer cambiar de esa aplicación? Se me ocurren dos cosas:&lt;/p&gt;

&lt;p&gt;- El mensaje&lt;/p&gt;

&lt;p&gt;- La forma de procesarlo&lt;/p&gt;

&lt;p&gt;Son dos responsabilidades, que podemos asignarlas a dos clases nuevas, digamos, MessageProvider:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,courier,monospace;"&gt; &lt;span&gt;public&lt;/span&gt; &lt;span&gt;class&lt;/span&gt; MessageProvider
 {
 &lt;span&gt;public&lt;/span&gt; &lt;span&gt;string&lt;/span&gt; Message { &lt;span&gt;get&lt;/span&gt;; &lt;span&gt;set&lt;/span&gt;; }
 }
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;y a MessageProcessor:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,courier,monospace;"&gt; &lt;span&gt;public&lt;/span&gt; &lt;span&gt;class&lt;/span&gt; MessageProcessor
 {
 &lt;span&gt;public&lt;/span&gt; MessageProvider Provider { &lt;span&gt;get&lt;/span&gt;; &lt;span&gt;set&lt;/span&gt;; }
 &lt;span&gt;public&lt;/span&gt; &lt;span&gt;void&lt;/span&gt; Process()
 {
 Console.WriteLine(&lt;span&gt;this&lt;/span&gt;.Provider.Message);
 }
 }
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Nuestro Hello World puede quedar ahora de esta forma:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,courier,monospace;"&gt; &lt;span&gt;static&lt;/span&gt; &lt;span&gt;void&lt;/span&gt; Main(&lt;span&gt;string&lt;/span&gt;[] args)
 {
 MessageProvider provider = &lt;span&gt;new&lt;/span&gt; MessageProvider() { Message = &amp;quot;&lt;span&gt;Hello, World&lt;/span&gt;&amp;quot; };
 MessageProcessor processor = &lt;span&gt;new&lt;/span&gt; MessageProcessor() { Provider = provider };
 processor.Process();
 }
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Vean que creamos los dos objetos de dos clases concretas, y los “conectamos”: como el MessageProcessor necesita de un MessageProvider, se lo proveemos mediante una propiedad (podríamos haberlo hecho mediante un parámetro en el constructor). Lo que estamos haciendo es construir un grafo de objetos, y dada la forma en que colaboran entre ellos, el grafo lo armamos nosotros. La alternativa sería: DENTRO de MessageProcessor crear un MessageProvider y usarlo. Pero eso dejaría acoplada la responsabilidad de cuál mensaje procesar al propio MessageProcessor. De la forma adoptada arriba, si queremos cambiar el mensaje, NO ALTERAMOS el código de MessageProcessor. A este objeto “le llueve del cielo” su colaborador. Vemos la aparición de un camino a seguir: los “new” de los objetos colaboradores, no están en el código de los consumidores de esos colaboradores. Más adelante, pasaremos a ejemplos más de la vida real. Pero por ahora, exploremos estos temas con ejemplo sencillo. Luego, el problema (armar el grafo de objetos) y la solución (lo armamos “por fuera” de los objetos) será la misma, con variantes, en ejemplos medios y complejos.&lt;/p&gt;

&lt;p&gt;Próximo paso: ahora que tenemos objetos que se hacen cargo de las responsabilidades que descubrimos, podemos refinar el ejemplo: ahora, MessageProcessor está acoplado a una clase concreta MessageProvider. Pero ¿qué necesita realmente MessageProcessor? En lugar de consumir un objeto de una clase concreta, ahora que tenemos un mini caso de uso codificado, podemos extraer, “descubrir” la interface que necesita consumir MessageProcessor. Y ya que estamos, también extraer, descubrir la interface, la conducta expuesta de cualquier MessageProcessor que se nos ocurra mañana. Pueden hacerlo a mano, o apelar a las capacidades de Refactoring, Extract Interface de Visual Studio. Tenemos IMessageProvider:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,courier,monospace;"&gt; &lt;span&gt;public&lt;/span&gt; &lt;span&gt;interface&lt;/span&gt; IMessageProvider
 {
 &lt;span&gt;string&lt;/span&gt; Message { &lt;span&gt;get&lt;/span&gt;; &lt;span&gt;set&lt;/span&gt;; }
 }
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;IMessageProcessor:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,courier,monospace;"&gt; &lt;span&gt;public&lt;/span&gt; &lt;span&gt;interface&lt;/span&gt; IMessageProcessor
 {
 &lt;span&gt;void&lt;/span&gt; Process();
 IMessageProvider Provider { &lt;span&gt;get&lt;/span&gt;; &lt;span&gt;set&lt;/span&gt;; }
 }
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Y nuestras clases ahora implementan y esperan esas interfaces:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,courier,monospace;"&gt; &lt;span&gt;public&lt;/span&gt; &lt;span&gt;class&lt;/span&gt; MessageProvider : HelloWorldInterfacesExample.IMessageProvider
 {
 &lt;span&gt;public&lt;/span&gt; &lt;span&gt;string&lt;/span&gt; Message { &lt;span&gt;get&lt;/span&gt;; &lt;span&gt;set&lt;/span&gt;; }
 }
&lt;/pre&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,courier,monospace;"&gt; &lt;span&gt;public&lt;/span&gt; &lt;span&gt;class&lt;/span&gt; MessageProcessor : HelloWorldInterfacesExample.IMessageProcessor
 {
 &lt;span&gt;public&lt;/span&gt; IMessageProvider Provider { &lt;span&gt;get&lt;/span&gt;; &lt;span&gt;set&lt;/span&gt;; }
 &lt;span&gt;public&lt;/span&gt; &lt;span&gt;void&lt;/span&gt; Process()
 {
 Console.WriteLine(&lt;span&gt;this&lt;/span&gt;.Provider.Message);
 }
 }
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Vemos que MessageProcessor es UNA implementación de IMessageProcessor, y que no espera un MessageProvider, sino que se las arregla con cualquier implementación, actual o futura, de IMessageProvider. Como antes, él no se preocupa de crear esa instancia ayudante, sino que alguien proveerá.&lt;/p&gt;

&lt;p&gt;Nuestra invocación queda:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="font-size:12px;margin:0em;width:100%;font-family:consolas,courier,monospace;"&gt; &lt;span&gt;static&lt;/span&gt; &lt;span&gt;void&lt;/span&gt; Main(&lt;span&gt;string&lt;/span&gt;[] args)
 {
 IMessageProvider provider = &lt;span&gt;new&lt;/span&gt; MessageProvider() { Message = &amp;quot;&lt;span&gt;Hello, World&lt;/span&gt;&amp;quot; };
 IMessageProcessor processor = &lt;span&gt;new&lt;/span&gt; MessageProcessor() { Provider = provider };
 processor.Process();
 }
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Por ahora, no parece que ganemos mucho (para este ejemplo simple). Si tenemos que cambiar el proveedor del mensaje, el mensaje, o la forma de procesarlo (por ejemplo, que genere, en lugar de un mensaje en pantalla, otra cosa, como un archivo PDF o una página web), tenemos que tocar el código de nuestra rutina de inicio. Exploraremos cómo, ayudados por algún framework, conseguir que ese armado y esos datos se deleguen a configuración.&lt;/p&gt;

&lt;p&gt;Código de los ejemplos en &lt;a href="http://cid-9f903f3d6db0c176.office.live.com/self.aspx/Examples/Hogwarts/HelloWorldObjectsExample.zip" target="_blank"&gt;HelloWorldObjectsExample.zip&lt;/a&gt; y &lt;a href="http://cid-9f903f3d6db0c176.office.live.com/self.aspx/Examples/Hogwarts/HelloWorldInterfacesExample.zip" target="_blank"&gt;HelloWorldInterfacesExample.zip&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nos leemos!&lt;/p&gt;

&lt;p&gt;Angel “Java” Lopez 
  &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1773878" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Cursos/default.aspx">Cursos</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp.NET/default.aspx">C Sharp.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Hogwarts/default.aspx">Hogwarts</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Inversion+of+Control/default.aspx">Inversion of Control</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Dependency+Injection/default.aspx">Dependency Injection</category></item></channel></rss>