<?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>Omar del Valle Rodríguez</title><link>http://geeks.ms/blogs/omarvr/default.aspx</link><description>Compartir puede significar enseñar o aprender...</description><dc:language /><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>DDD: 2- Framework de IoC (Service Pack 1)</title><link>http://geeks.ms/blogs/omarvr/archive/2011/11/22/ddd-2-framework-de-ioc-service-pack-1.aspx</link><pubDate>Tue, 22 Nov 2011 22:53:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:201837</guid><dc:creator>Omar del Valle Rodríguez</dc:creator><slash:comments>7</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/rsscomments.aspx?PostID=201837</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/commentapi.aspx?PostID=201837</wfw:comment><comments>http://geeks.ms/blogs/omarvr/archive/2011/11/22/ddd-2-framework-de-ioc-service-pack-1.aspx#comments</comments><description>&lt;p&gt;&lt;span style="font-family:calibri;font-size:small;"&gt;
&lt;p&gt;Despu&amp;eacute;s de la &amp;uacute;ltima sacudida recibida &lt;img src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/wlEmoticon_2D00_sadsmile_5F00_292C0F4F.png" alt="Sad smile" class="wlEmoticon wlEmoticon-sadsmile" style="border-bottom-style:none;border-left-style:none;border-top-style:none;border-right-style:none;" /&gt; por la encapsulaci&amp;oacute;n del Container que hicimos en el art&amp;iacute;culo anterior, sacamos este Service Pack 1 &lt;img src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/wlEmoticon_2D00_smile_5F00_4F8DF29A.png" alt="Smile" class="wlEmoticon wlEmoticon-smile" style="border-bottom-style:none;border-left-style:none;border-top-style:none;border-right-style:none;" /&gt; y de paso cuento un poco c&amp;oacute;mo llegamos aqu&amp;iacute;.&lt;/p&gt;
&lt;p&gt;Cuando me pasan estas cosas, siempre recuerdo el pasaje de una lectura que tengo por casa&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Denis Cochin preparo un estudio sobre Qu&amp;iacute;mica y lo presento a Pasteur. El trabajo comenzaba con las palabras. &amp;ldquo;Se sabe que...&amp;ldquo;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;- &amp;iquest;Que es lo que se sabe? - Interrumpi&amp;oacute; Pasteur al leerlo. - No se sabe nada. &lt;br /&gt;- Pero se&amp;ntilde;or - Contesto Cochin - lo que iba a citar es un trabajo de usted.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;- No importa - replico Pasteur. - Yo podr&amp;iacute;a haberme equivocado. Empiece Ud. de nuevo&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Tras los comentarios de &lt;a href="http://geeks.ms/blogs/unai/default.aspx"&gt;Unai&lt;/a&gt; y &lt;a href="http://geeks.ms/blogs/etomas/default.aspx"&gt;Eduard&lt;/a&gt; m&amp;aacute;s la referencia al art&amp;iacute;culo de &lt;a href="http://blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx"&gt;Mark&lt;/a&gt; sobre el patr&amp;oacute;n o anti-patr&amp;oacute;n Service-Locator (Martin Fowler, 2004), hab&amp;iacute;a que profundizar m&amp;aacute;s en el tema, as&amp;iacute; que sin pensarlo dos veces me compr&amp;eacute; el libro de &amp;ldquo;&lt;a href="http://manning.com/seemann/"&gt;Dependency Injection in .NET&lt;/a&gt;&amp;rdquo; el cual recomiendo much&amp;iacute;simo por la claridad en el contenido, adem&amp;aacute;s de estar orientado directamente a NET.&lt;/p&gt;
&lt;p&gt;En el libro, cuando Mark habla del Service Locator como un anti-patr&amp;oacute;n, dice: &amp;ldquo;Some people consider it a proper design pattern, whereas others (me included) consider it an anti-pattern.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Tras esta definici&amp;oacute;n no puedo evitar preguntarme &amp;iquest;Y en qu&amp;eacute; bando me pongo yo? Es evidente que la opini&amp;oacute;n de Eduard, Unai, Mark y seguramente la de muchos otros, pesa much&amp;iacute;simo, as&amp;iacute; que lo m&amp;aacute;s probable es que termine m&amp;aacute;s r&amp;aacute;pido si busco alguna deficiencia en la implementaci&amp;oacute;n anterior que me lleve finalmente a verlo como ellos.&lt;/p&gt;
&lt;p&gt;Tras no mucho tiempo&amp;hellip; me imagin&amp;eacute; la siguiente situaci&amp;oacute;n:&lt;/p&gt;
&lt;p&gt;Tengo varios controladores (MVC) que usan inyecci&amp;oacute;n de dependencia con uno o varios servicios (Application services), tengo servicios que usan dependencias a uno o m&amp;aacute;s repositorios, tengo varios repositorios que usan dependencia a una unidad de trabajo, tengo una unidad de trabajo que depende de una cadena de conexi&amp;oacute;n. En esa situaci&amp;oacute;n, tendr&amp;eacute; en mis controladores llamadas al Resolve del container para crear los servicios, en los servicios llamadas al Resolve para crear instancias de los repositorios, tendr&amp;eacute; tambi&amp;eacute;n llamadas al Resolve en los repositorios para recuperar la unidad de trabajo y as&amp;iacute; en toda mi arquitectura... &lt;/p&gt;
&lt;p&gt;Salta a simple vista que mis controladores dependen de mis servicios y del Service Locator. Los servicios dependen de los repositorios y del Service Locator, los repositorios dependen de la unidad de trabajo y del Service Locator. &amp;iquest;Qu&amp;eacute; pasa si quiero reutilizar los repositorios? &amp;iquest;O si quiero reutilizar los servicios? &amp;iquest;O si quiero reutilizar mi unidad de trabajo? Pues que en todo momento depender&amp;eacute; del Service Locator&amp;hellip; &lt;/p&gt;
&lt;p&gt;&lt;img src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/wlEmoticon_2D00_sadsmile_5F00_292C0F4F.png" alt="Sad smile" class="wlEmoticon wlEmoticon-sadsmile" style="border-bottom-style:none;border-left-style:none;border-top-style:none;border-right-style:none;" /&gt; No segu&amp;iacute; buscando&amp;hellip; mi objetivo era estar desacoplado del Framework de IoC y termin&amp;eacute; atando toda la arquitectura.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;iquest;C&amp;oacute;mo soluciono esto entonces?&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;-Constructor Inyection &lt;br /&gt;-Property Injection &lt;br /&gt;-&amp;hellip;&lt;/p&gt;
&lt;p&gt;Si mis controladores recibieran los servicios que necesitan para trabajar mediante el constructor, no necesitar&amp;iacute;a una referencia al Service Locator&amp;hellip; y lo mismo pasa en toda la cadena de inyecci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;iquest;C&amp;oacute;mo funciona esto?&lt;/strong&gt; Imaginen que tengo&amp;hellip;&lt;/p&gt;
&lt;p&gt;Controller(IService srv) &amp;ndash; Service(IRepository repo) &amp;ndash; Repository(IUnitofWork uow) &amp;ndash; UnitOfWork()&lt;/p&gt;
&lt;p&gt;1- Un controlador necesita una instancia de un servicio, se intenta crear una instancia de ese servicio. &lt;br /&gt;2- Para crear el servicio se necesita un repositorio, se intenta crear una instancia del repositorio. &lt;br /&gt;3- Para crear el repositorio se necesita una unidad de trabajo, se intenta crear la unidad de trabajo. &lt;br /&gt;4- Se crea la unidad de trabajo (no depende de nadie). &lt;br /&gt;5- A partir de aqu&amp;iacute;, se inyecta la unidad de trabajo al repositorio, el repositorio al servicio y el servicio al controlador.&lt;/p&gt;
&lt;p&gt;Este algoritmo me dice que todo empieza desde un punto &amp;uacute;nico. A este punto Mark lo llama Composition Root. &amp;ldquo;A COMPOSITION ROOT is a (preferably) unique location in an application where modules are composed together.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Un DI Container es quien me dice qui&amp;eacute;n es el Container utilizado en mi aplicaci&amp;oacute;n y el encargado de componer todo el &lt;a href="http://es.wikipedia.org/wiki/Grafo"&gt;grafo de objetos&lt;/a&gt;. Este debe ser referenciado &amp;uacute;nicamente desde el Composition root (De aqu&amp;iacute; que Eduard y Unai no vean la necesidad de abstraer el Container) y se inicializa solo una vez en todo el ciclo de vida de la aplicaci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;Conociendo un poco m&amp;aacute;s que ayer, decid&amp;iacute; hacer &amp;ldquo;refactoring&amp;rdquo; a todo lo visto ayer (Por llamarle de una forma menos dura al hecho de borrar todas las interfaces e implementaciones de mi Service Locator). Despu&amp;eacute;s de un rato, me qued&amp;oacute; esto:&lt;/p&gt;
&lt;p&gt;Mi DI Container. &amp;hellip;&lt;/p&gt;
&lt;code class="prettyprint lang-cs"&gt;
&lt;p&gt;public static class UnityContainerFactory &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private static readonly IUnityContainer _container;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; static UnityContainerFactory() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _container = new UnityContainer(); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Configure(); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private static void Configure() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var section = (UnityConfigurationSection)ConfigurationManager.GetSection(&amp;quot;unity&amp;quot;); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; section.Configure(_container);&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Aditional Configuration &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Container.RegisterType&amp;lt;IBaseType, ModuleAType&amp;gt;(&amp;quot;moduleA&amp;quot;) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Container.RegisterType&amp;lt;IBaseType, ModuleBType&amp;gt;(&amp;quot;moduleB&amp;quot;) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static IUnityContainer GetContainer() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return _container; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;
&lt;/code&gt;
&lt;p&gt;&lt;strong&gt;&amp;iquest;Qui&amp;eacute;n ser&amp;iacute;a mi Composition Root?&lt;/strong&gt; Pues ya esto depende del tipo de aplicaci&amp;oacute;n que se vaya a crear, ya que cada aplicaci&amp;oacute;n puede tener una definici&amp;oacute;n diferente para su &amp;ldquo;&amp;uacute;nico punto de entrada&amp;rdquo;. Por ejemplo, para una aplicaci&amp;oacute;n MVC, Mark aconseja un IControllerFactory, aunque si es para MVC3, yo prefiero el IDependencyResolver. &lt;/p&gt;
&lt;p&gt;Mi Composition Root para MVC3 ser&amp;iacute;a:&lt;/p&gt;
&lt;code class="prettyprint lang-cs"&gt;
&lt;p&gt;public class UnityDependencyResolver : IDependencyResolver &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private readonly IUnityContainer _container;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region Implementation of IDependencyResolver&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public UnityDependencyResolver(IUnityContainer container) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _container = container; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public object GetService(Type serviceType) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return _container.IsRegistered(serviceType) ? _container.Resolve(serviceType) : null; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public IEnumerable&amp;lt;object&amp;gt; GetServices(Type serviceType) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return _container.ResolveAll&amp;lt;object&amp;gt;().Where(s =&amp;gt; s.GetType() == serviceType); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;} &lt;/p&gt;
&lt;/code&gt;
&lt;p&gt;Aqu&amp;iacute; puedes encontrar un peque&amp;ntilde;o &lt;a href="http://stevesmithblog.com/blog/how-do-i-use-structuremap-with-asp-net-mvc-3/"&gt;post&lt;/a&gt; de Steve explicando la implementaci&amp;oacute;n anterior.&lt;/p&gt;
&lt;p&gt;Para el caso de un servicio WCF me gust&amp;oacute; la forma en que lo implementaron en la &lt;a href="http://microsoftnlayerapp.codeplex.com/"&gt;gu&amp;iacute;a de arquitectura N Layer&lt;/a&gt; donde se implementa la interfaz IInstanceProvider:&lt;/p&gt;
&lt;code class="prettyprint lang-cs"&gt;
&lt;p&gt;public class UnityDependencyProvider : IInstanceProvider &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private readonly IUnityContainer _container; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private readonly Type _serviceType;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public UnityDependencyProvider(Type serviceType) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (serviceType == null) throw new ArgumentNullException(&amp;quot;serviceType&amp;quot;);&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _serviceType = serviceType; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _container = UnityContainerFactory.GetContainer();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region Implementation of IInstanceProvider&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public object GetInstance(InstanceContext instanceContext) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return GetInstance(instanceContext, null); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public object GetInstance(InstanceContext instanceContext, Message message) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return _container.Resolve(_serviceType); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void ReleaseInstance(InstanceContext instanceContext, object instance) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (instance is IDisposable) ((IDisposable)instance).Dispose(); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion &lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;Y luego creamos el atributo con el que marcaremos los servicios WCF que necesiten inyecci&amp;oacute;n de dependencias&amp;hellip;&lt;/p&gt;
&lt;p&gt;public class UnityDependencyProviderServiceBehavior : Attribute, IServiceBehavior &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region Implementation of IServiceBehavior&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void AddBindingParameters(ServiceDescription serviceDescription, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ServiceHostBase serviceHostBase, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Collection&amp;lt;ServiceEndpoint&amp;gt; endpoints, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; BindingParameterCollection bindingParameters) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (var dispatcher in serviceHostBase.ChannelDispatchers.OfType&amp;lt;ChannelDispatcher&amp;gt;()) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dispatcher.Endpoints.ToList(). &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ForEach(endpoint =&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; endpoint.DispatchRuntime.InstanceProvider = new UnityDependencyProvider(serviceDescription.ServiceType); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion &lt;br /&gt;}&lt;/p&gt;
&lt;/code&gt;
&lt;p&gt;&amp;quot;As you can see, it took me a couple of years of intense use to realize the shortcomings of SERVICE LOCATOR and that better alternatives existed. For this reason, I find it easy to understand why so many developers find it attractive&amp;hellip;&amp;rdquo; (Gracias Mark) &lt;img src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/wlEmoticon_2D00_smile_5F00_4F8DF29A.png" alt="Smile" class="wlEmoticon wlEmoticon-smile" style="border-bottom-style:none;border-left-style:none;border-top-style:none;border-right-style:none;" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Los test&amp;hellip;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;El problema de los test est&amp;aacute; en que no tenemos un evento al cual nos podamos subscribir ni interfaz que implementar&amp;hellip; Entonces, &lt;a href="http://scottdepouw.com/blog/testing-the-ioc-container/"&gt;&amp;iquest;C&amp;oacute;mo creo los test sobre el IoC Container?&lt;/a&gt; by Scott&amp;hellip;&lt;/p&gt;
&lt;p&gt;Basados en las interfaces IA, IB y las clases A y B que escribimos en el art&amp;iacute;culo anterior, tendr&amp;iacute;amos los siguientes test:&lt;/p&gt;
&lt;code class="prettyprint lang-cs"&gt;
&lt;p&gt;[TestClass] &lt;br /&gt;public class IocTest &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private readonly IUnityContainer _ioc;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// En los test, este es mi punto de entrada (Composition root) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public IocTest() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _ioc = UnityContainerFactory.GetContainer(); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [TestMethod] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void TestCreateObjetWithoutConstructorParameters() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var a = _ioc.Resolve&amp;lt;IA&amp;gt;();&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.IsNotNull(a); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.AreEqual(1, a.ObjectId); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [TestMethod] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void TestCreateObjetWithConstructorParameters() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //var a = new A();&amp;nbsp; Ya no necesitamos hacer esto... &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //el framework de IoC se encarga de construir IA&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var b = _ioc.Resolve&amp;lt;IB&amp;gt;();&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.IsNotNull(b); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.AreEqual(1, b.ParamInjector.ObjectId); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;} &lt;/p&gt;
&lt;/code&gt;
&lt;p&gt;Los elementos de configuraci&amp;oacute;n, ya podemos inyectarlos tal y como nos ped&amp;iacute;a Juanma:&lt;/p&gt;
&lt;code class="prettyprint lang-cs"&gt;
&lt;p&gt;[TestClass] &lt;br /&gt;public class ConfigTest &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private readonly IUnityContainer _ioc;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public ConfigTest() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _ioc = UnityContainerFactory.GetContainer(); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [TestMethod] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void TestConfiguration() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var global = new Global(new AppSettingsHelper()); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var settings = global.Settings;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.AreEqual(&amp;quot;My Project DDD&amp;quot;, settings.Name); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.AreEqual(&amp;quot;es-ES&amp;quot;, settings.LanguageDefault); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.AreEqual(&amp;quot;dd-MM-yyyy HH:mm&amp;quot;, settings.DateTimeFormat); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.AreEqual(1, settings.TimeZoneOffset);&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.IsInstanceOfType(global.SettingsHelper.GetBoolean(&amp;quot;bool&amp;quot;), typeof(bool)); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [TestMethod] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void TestIocConfiguration() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var global = _ioc.Resolve&amp;lt;IGlobalSettings&amp;gt;();&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.IsNotNull(global); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.IsNotNull(global.Settings); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.IsNotNull(global.SettingsHelper);&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.IsInstanceOfType(global.Settings, typeof(AppConfigurationElement)); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.IsInstanceOfType(global.SettingsHelper, typeof(AppSettingsHelper)); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;}&lt;/p&gt;
&lt;/code&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/test_2D00_config_5F00_4802832D.png"&gt;&lt;img height="342" width="741" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/test_2D00_config_5F00_thumb_5F00_5F4D879E.png" alt="test-config" border="0" title="test-config" style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Gracias a Unai y a Eduard por hacer posible esta mejora&amp;hellip;&lt;/em&gt;&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;PD: A&amp;uacute;n no he probado los m&amp;oacute;dulos implementados para MVC3 o para WCF&amp;hellip; ya os contar&amp;eacute; &lt;img src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/wlEmoticon_2D00_winkingsmile_5F00_2D263754.png" alt="Winking smile" class="wlEmoticon wlEmoticon-winkingsmile" style="border-bottom-style:none;border-left-style:none;border-top-style:none;border-right-style:none;" /&gt;&lt;/p&gt;
&lt;p&gt;Salu2&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=201837" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/omarvr/archive/tags/POO/default.aspx">POO</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/arquitectura/default.aspx">arquitectura</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/NET/default.aspx">NET</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/DDD/default.aspx">DDD</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/IoC/default.aspx">IoC</category></item><item><title>DDD: 2- Framework de IoC (parte 2)</title><link>http://geeks.ms/blogs/omarvr/archive/2011/11/20/ddd-2-framework-de-ioc-parte-2.aspx</link><pubDate>Sun, 20 Nov 2011 11:26:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:201779</guid><dc:creator>Omar del Valle Rodríguez</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/rsscomments.aspx?PostID=201779</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/commentapi.aspx?PostID=201779</wfw:comment><comments>http://geeks.ms/blogs/omarvr/archive/2011/11/20/ddd-2-framework-de-ioc-parte-2.aspx#comments</comments><description>&lt;p&gt;&lt;span style="font-family:calibri;font-size:small;"&gt;
&lt;p&gt;En el &lt;a href="http://geeks.ms/blogs/omarvr/archive/2011/11/19/ddd-2-framework-de-ioc-parte-1.aspx"&gt;art&amp;iacute;culo anterior&lt;/a&gt; implementamos todas las interfaces necesarias para usar algunos elementos de configuraci&amp;oacute;n a nivel de aplicaci&amp;oacute;n. Entre estos elementos estaba el Framework de IoC.&lt;/p&gt;
&lt;p&gt;En ese mismo art&amp;iacute;culo explic&amp;aacute;bamos por qu&amp;eacute; decidimos inyectar al Framework de dependecia, as&amp;iacute; que hoy nos dedicaremos a implementar todas las interfaces y realizar algunos test. &lt;/p&gt;
&lt;p&gt;Antes de empezar, deciros que he realizado una peque&amp;ntilde;a modificaci&amp;oacute;n a la interfaz &lt;strong&gt;IContainerConfiguration&lt;/strong&gt; que vimos en el art&amp;iacute;culo anterior. Soy de los que cree que cuando alg&amp;uacute;n c&amp;oacute;digo (mio o no) queda digno de &amp;ldquo;admirar&amp;rdquo; (lo cual no quiere decir &amp;ldquo;correcto&amp;rdquo; &lt;img src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/wlEmoticon_2D00_smilewithtongueout_5F00_64C74DEF.png" alt="Smile with tongue out" class="wlEmoticon wlEmoticon-smilewithtongueout" style="border-bottom-style:none;border-left-style:none;border-top-style:none;border-right-style:none;" /&gt;), me quedo rato mir&amp;aacute;ndolo a&amp;uacute;n d&amp;iacute;as o semanas despu&amp;eacute;s de haberlo implementado. Esto, adem&amp;aacute;s de parecer que pierdo el tiempo, me&amp;nbsp; ayuda a ver posibles refactoring que en su momento no vi. &lt;/p&gt;
&lt;p&gt;En uno de esos momentos de &amp;ldquo;bober&amp;iacute;a&amp;rdquo; me di cuenta que la interfaz IContainerConfiguration no necesita saber el QulifiedName para nada y que con el tipo era suficiente. Es verdad que de alguna forma debo recuperar el tipo, pero de eso que se encargue quien implemente la interfaz.&lt;/p&gt;
&lt;p&gt;IContainerConfiguration ahora quedar&amp;iacute;a as&amp;iacute;:&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint lang-cs"&gt;public interface IContainerConfiguration &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Type IocObjectType { get; } &lt;br /&gt;} &lt;br /&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Despu&amp;eacute;s de hecho el cambio, entramos en materia. &lt;/p&gt;
&lt;p&gt;Pensando con el coraz&amp;oacute;n y no en el performance, voy a utilizar como Framework de inyecci&amp;oacute;n de dependencia el Unity de Microsoft, pero recuerden, de la forma que lo hemos implementado podr&amp;iacute;amos usar cualquiera siempre que implementemos la interfaz IContainer. &lt;/p&gt;
&lt;p&gt;Para temas de configuraci&amp;oacute;n, usar&amp;eacute; el archivo de configuraci&amp;oacute;n de la aplicaci&amp;oacute;n. Al igual que el framework de IoC, podr&amp;iacute;amos obtener la configuraci&amp;oacute;n de cualquier otro lado tan solo implementando las distintas interfaces.&lt;/p&gt;
&lt;p&gt;Empezamos con la implementaci&amp;oacute;n del UnityContainer, nuestro &amp;uacute;nico requerimiento es implementar la interfaz IContainer. &lt;/p&gt;
&lt;code class="prettyprint lang-cs"&gt;
&lt;p&gt;public sealed class UnityContainer : IContainer, IDisposable &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private readonly Microsoft.Practices.Unity.UnityContainer _container;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public UnityContainer() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _container = new Microsoft.Practices.Unity.UnityContainer(); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region Miembros de IContainer&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void InitializeContainer() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var section = (UnityConfigurationSection)ConfigurationManager.GetSection(&amp;quot;unity&amp;quot;); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; section.Configure(_container); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Retorna una nueva instancia del tipo T usando IoC &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;typeparam name=&amp;quot;T&amp;quot;&amp;gt;Tipo del nuevo objeto a instanciar&amp;lt;/typeparam&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;returns&amp;gt;Instancia del tipo generico T&amp;lt;/returns&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public T GetInstanceOf&amp;lt;T&amp;gt;() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return _container.Resolve&amp;lt;T&amp;gt;(); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Retorna una nueva instancia del tipo T usando IoC &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;typeparam name=&amp;quot;T&amp;quot;&amp;gt;Tipo del nuevo objeto a instanciar&amp;lt;/typeparam&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;typeparam name=&amp;quot;TParamType&amp;quot;&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Un par&amp;aacute;metro de tipo TParamType que se le pasa al construnctor de T &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/typeparam&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;returns&amp;gt;Instancia del tipo generico T&amp;lt;/returns&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public T GetInstanceOf&amp;lt;T, TParamType&amp;gt;(TParamType paramInjection) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _container.RegisterInstance(typeof(TParamType), paramInjection); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return _container.Resolve&amp;lt;T&amp;gt;(); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region Miembros de IDisposable&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// El Objeto UnityContainer del EnterpriseLibrary implementa IDisposable. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Al construir una instancia de este objeto dentro de nuestra clase, necesitamos &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// implementar dicha interfaz. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void Dispose() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _container.Dispose(); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion &lt;br /&gt;}&lt;/p&gt;
&lt;/code&gt;
&lt;p&gt;La idea no es entrar a analizar el UnityContainer de Microsoft, sino me gusta, uso otro y nada cambia en toda mi aplicaci&amp;oacute;n. De cualquier forma, por detallar un poco la implementaci&amp;oacute;n de la interfaz, vemos la inicializaci&amp;oacute;n de Unity en el m&amp;eacute;todo que provee la interfaz (InitializeContainer), luego usamos el Container para satisfacer los dos m&amp;eacute;todos de la interfaz que retornan una instancia de un objeto basado en su interfaz (con o sin par&amp;aacute;metro) y todo listo.&lt;/p&gt;
&lt;p&gt;&amp;iquest;Hacemos entonces unos Test a ver qu&amp;eacute; tal? Ah no, que no puedo, primero tengo que implementar todo el tema de configuraci&amp;oacute;n. Pues lo que adoro de esta arquitectura es precisamente esto, s&amp;iacute;, tengo que implementar el tema de configuraci&amp;oacute;n, pero como la misma sale de una interfaz, puedo hacerlo sin tener que llegar a implementar todo lo que se refiere al archivo de configuraci&amp;oacute;n. &lt;img src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/wlEmoticon_2D00_smile_5F00_3D20D1C5.png" alt="Smile" class="wlEmoticon wlEmoticon-smile" style="border-bottom-style:none;border-left-style:none;border-top-style:none;border-right-style:none;" /&gt;&lt;/p&gt;
&lt;code class="prettyprint lang-cs"&gt;
&lt;p&gt;class UnityConfiguration : IContainerConfiguration &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region Implementation of IContainerConfiguration &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Type IocObjectType &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return typeof(Project.IoC.EnterpriseLibrary.UnityContainer); } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion &lt;br /&gt;} &lt;/p&gt;
&lt;/code&gt;
&lt;p&gt;Aqu&amp;iacute; implemento la interfaz de configuraci&amp;oacute;n para el IoC y retorno directamente el tipo que implementa el IContainer. (Nota: El tipo UnityContainer que retorno aqu&amp;iacute; no es el de Microsoft, es el m&amp;iacute;o que implementa la interfaz IContainer).&lt;/p&gt;
&lt;p&gt;Voy a crearme unos objetos bien simples para realizar los test &lt;/p&gt;
&lt;code class="prettyprint lang-cs"&gt;
&lt;p&gt;public interface IA &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int ObjectID { get; } &lt;br /&gt;} &lt;/p&gt;
&lt;p&gt;public interface IB &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IA ObjectInjection { get; } &lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;public class A : IA &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public A() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ObjectID = 1; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region Implementation of IA&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public int ObjectID { get; private set; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion &lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;public class B : IB &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public B(IA paramInjection) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ObjectInjection = paramInjection; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region Implementation of IB&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public IA ObjectInjection { get; private set; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion &lt;br /&gt;}&lt;/p&gt;
&lt;/code&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Configuramos el Unity de Microsft para crear los Alias y los mapeos y vamos por los test. &lt;/p&gt;
&lt;p&gt;&amp;lt;configSections&amp;gt; &lt;br /&gt;&amp;nbsp; &amp;lt;section name=&amp;quot;unity&amp;quot; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; type=&amp;quot;Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Microsoft.Practices.Unity.Configuration&amp;quot; /&amp;gt; &lt;br /&gt;&amp;lt;/configSections&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;unity&amp;gt; &lt;br /&gt;&amp;nbsp; &amp;lt;typeAliases&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;typeAlias alias=&amp;quot;IA&amp;quot; type=&amp;quot;Solution.Test.Infrastructure.IoC.IA, Solution.Test&amp;quot; /&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;typeAlias alias=&amp;quot;IB&amp;quot; type=&amp;quot;Solution.Test.Infrastructure.IoC.IB, Solution.Test&amp;quot; /&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;typeAlias alias=&amp;quot;A&amp;quot; type=&amp;quot;Solution.Test.Infrastructure.IoC.A, Solution.Test&amp;quot; /&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;typeAlias alias=&amp;quot;B&amp;quot; type=&amp;quot;Solution.Test.Infrastructure.IoC.B, Solution.Test&amp;quot; /&amp;gt; &lt;br /&gt;&amp;nbsp; &amp;lt;/typeAliases&amp;gt; &lt;br /&gt;&amp;nbsp; &amp;lt;containers&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;container&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;register type=&amp;quot;IA&amp;quot; mapTo=&amp;quot;A&amp;quot; /&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;register type=&amp;quot;IB&amp;quot; mapTo=&amp;quot;B&amp;quot; /&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/container&amp;gt; &lt;br /&gt;&amp;nbsp; &amp;lt;/containers&amp;gt; &lt;br /&gt;&amp;lt;/unity&amp;gt;&lt;/p&gt;
&lt;p&gt;Los test:&lt;/p&gt;
&lt;code class="prettyprint lang-cs"&gt;
&lt;p&gt;[TestClass] &lt;br /&gt;public class IocTest &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private readonly IContainer _ioc; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public IocTest() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _ioc = new IocFactory().Create(new UnityConfiguration()); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [TestMethod] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void TestCreateObjetWithoutConstructorParameters() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var a = _ioc.GetInstanceOf&amp;lt;IA&amp;gt;();&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.IsNotNull(a); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.AreEqual(1, a.ObjectID); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [TestMethod] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void TestCreateObjetWithConstructorParameters() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var a = new A(); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var b = _ioc.GetInstanceOf&amp;lt;IB, IA&amp;gt;(a);&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.IsNotNull(b); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.AreEqual(1, b.ObjectInjection.ObjectID); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;}&lt;/p&gt;
&lt;/code&gt;
&lt;p&gt;&lt;img src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/wlEmoticon_2D00_flirtmale_5F00_4A86E4CB.png" alt="Flirt male" class="wlEmoticon wlEmoticon-flirtmale" style="border-bottom-style:none;border-left-style:none;border-top-style:none;border-right-style:none;" /&gt; Me encanta este momento&amp;hellip; &lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/test_2D00_ioc_5F00_150E22A6.png"&gt;&lt;img height="175" width="522" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/test_2D00_ioc_5F00_thumb_5F00_0F530900.png" alt="test-ioc" border="0" title="test-ioc" style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Bien, pasemos del sentimentalismo y la adoraci&amp;oacute;n del color verde del Success &lt;img src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/wlEmoticon_2D00_openmouthedsmile_5F00_25C5A787.png" alt="Open-mouthed smile" class="wlEmoticon wlEmoticon-openmouthedsmile" style="border-bottom-style:none;border-left-style:none;border-top-style:none;border-right-style:none;" /&gt; y vayamos a la configuraci&amp;oacute;n. La implementaci&amp;oacute;n de la configuraci&amp;oacute;n del framework de IoC desde el archivo de configuraci&amp;oacute;n quedar&amp;iacute;a de la siguiente forma: &lt;/p&gt;
&lt;code class="prettyprint lang-cs"&gt;
&lt;p&gt;public class ContainerConfigurationElement : ConfigurationElement, IContainerConfiguration &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ConfigurationProperty(&amp;quot;unityType&amp;quot;, IsRequired = true)] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string IocQualifiedName &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return (string)this[&amp;quot;unityType&amp;quot;]; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set { this[&amp;quot;unityType&amp;quot;] = value; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Type IocObjectType &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return Type.GetType(IocQualifiedName); } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;} &lt;/p&gt;
&lt;/code&gt;
&lt;p&gt;Recuerden que ya la propiedad que nos da el QualifiedName no pertenece a la interfaz, sin embargo s&amp;iacute; que la implementamos cuando queremos obtener qui&amp;eacute;n ser&amp;aacute; nuestro&amp;nbsp; Framework de IoC desde la configuraci&amp;oacute;n. &lt;/p&gt;
&lt;p&gt;Hagamos lo mismo para los Settings de mi aplicaci&amp;oacute;n:&lt;/p&gt;
&lt;code class="prettyprint lang-cs"&gt;
&lt;p&gt;public class AppConfigurationElement : ConfigurationElement, IAppConfigurationElement &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region Implementation of IAppConfigurationElement &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ConfigurationProperty(&amp;quot;name&amp;quot;, IsRequired = true)] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string Name &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return (string)this[&amp;quot;name&amp;quot;]; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this[&amp;quot;name&amp;quot;] = value; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ConfigurationProperty(&amp;quot;datetimeFormat&amp;quot;, IsRequired = false, DefaultValue = null)] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string DateTimeFormat &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var dtFormat = (string)this[&amp;quot;datetimeFormat&amp;quot;] ?? &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; new CultureInfo(LanguageDefault, false).DateTimeFormat.ToString(); &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return dtFormat; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this[&amp;quot;datetimeFormat&amp;quot;] = value; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ConfigurationProperty(&amp;quot;languageDefault&amp;quot;, IsRequired = true)] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string LanguageDefault &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return (string)this[&amp;quot;languageDefault&amp;quot;]; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this[&amp;quot;languageDefault&amp;quot;] = value; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ConfigurationProperty(&amp;quot;timeZoneOffset&amp;quot;, IsRequired = false, DefaultValue = 0D)] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public double TimeZoneOffset &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return (double)this[&amp;quot;timeZoneOffset&amp;quot;]; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this[&amp;quot;timeZoneOffset&amp;quot;] = value; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion &lt;br /&gt;}&lt;/p&gt;
&lt;/code&gt;
&lt;p&gt;Ahora ya podemos&amp;nbsp; implementar la interfaz que agrupa los elementos de configuraci&amp;oacute;n.&lt;/p&gt;
&lt;code class="prettyprint lang-cs"&gt;
&lt;p&gt;public class AppConfigurationSection : ConfigurationSection, IAppConfigurationSection &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ConfigurationProperty(&amp;quot;Setting&amp;quot;)] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private AppConfigurationElement ConfigSettings &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return (AppConfigurationElement)this[&amp;quot;Setting&amp;quot;]; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this[&amp;quot;Setting&amp;quot;] = value; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [ConfigurationProperty(&amp;quot;IocConfiguration&amp;quot;)]&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private ContainerConfigurationElement ConfigIocConfiguration &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return (ContainerConfigurationElement)this[&amp;quot;IocConfiguration&amp;quot;]; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set { this[&amp;quot;IocConfiguration&amp;quot;] = value; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region Implementation of IAppConfigurationSection&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public IContainerConfiguration IocConfiguration &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return ConfigIocConfiguration; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set { ConfigIocConfiguration = (ContainerConfigurationElement) value; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public IAppConfigurationElement Settings &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return ConfigSettings; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set { ConfigSettings = (AppConfigurationElement) value; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion &lt;br /&gt;}&lt;/p&gt;
&lt;/code&gt;
&lt;p&gt;Vean que hemos tenido que definir propiedades que retornen un ConfigurationElement. Esto es requerido para poder leer las configuraciones del archivo de configuraci&amp;oacute;n, pero yo en ning&amp;uacute;n momento deseo que esos tipos sean conocidos por mi aplicaci&amp;oacute;n (recuerden que trabajamos ajenos a la tecnolog&amp;iacute;a que usemos). Es por eso que esta clase crea las propiedades concretas para la configuraci&amp;oacute;n como privadas y, las que usar&amp;aacute; mi aplicaci&amp;oacute;n (p&amp;uacute;blicas) retornan la interfaz del tipo creado.&lt;/p&gt;
&lt;p&gt;Por &amp;uacute;ltimo, implementamos IGlobalSettings. Aqu&amp;iacute; me implemento un Singleton a nivel de aplicaci&amp;oacute;n para acceder a mi configuraci&amp;oacute;n. Dos razones, tengo un &amp;uacute;nico punto de acceso (por eso el s&amp;iacute;ngleton) y los datos que guarda mi configuraci&amp;oacute;n no cambian durante todo el ciclo de vida de la aplicaci&amp;oacute;n (por eso digo que es a nivel de aplicaci&amp;oacute;n) &lt;/p&gt;
&lt;code class="prettyprint lang-cs"&gt;
&lt;p&gt;public sealed class Global : IGlobalSettings &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// Singleton. Thread safe. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private static readonly Lazy&amp;lt;Global&amp;gt; _instance = new Lazy&amp;lt;Global&amp;gt;(() =&amp;gt; new Global());&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// IocFactory. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private readonly IContainer _ioc;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private Global() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var cfg = (IAppConfigurationSection)ConfigurationManager.GetSection(&amp;quot;Project&amp;quot;);&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _ioc = new IocFactory().Create(cfg.IocConfiguration); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Settings = cfg.Settings; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static Global Application &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return _instance.Value; } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region IAppConfigurationSection Members&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public IContainer Ioc { get { return _ioc; } } &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public IAppConfigurationElement Settings { get; private set; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion &lt;br /&gt;}&lt;/p&gt;
&lt;/code&gt;
&lt;p&gt;Ya podemos ir a por los Test de configuraci&amp;oacute;n. El IoC ya lo probamos, por lo que con saber que el tipo retornado por la configuraci&amp;oacute;n es correcto (implementa IContainer), tengo suficiente &lt;/p&gt;
&lt;p&gt;Antes de escribir los test, creamos la configuraci&amp;oacute;n en el archivo de configuraci&amp;oacute;n de la aplicaci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;&amp;lt;configSections&amp;gt; &lt;br /&gt;&amp;nbsp; &amp;lt;section name=&amp;quot;Project&amp;quot; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; type=&amp;quot;Project.Settings.Config.AppConfigurationSection, Project.Settings.Config&amp;quot; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; requirePermission=&amp;quot;false&amp;quot; /&amp;gt; &lt;br /&gt;&amp;lt;/configSections&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;Project&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;lt;Setting name=&amp;quot;My Project DDD&amp;quot; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; languageDefault=&amp;quot;es-ES&amp;quot; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; datetimeFormat=&amp;quot;dd-MM-yyyy HH:mm&amp;quot; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; timeZoneOffset=&amp;quot;1&amp;quot;&amp;nbsp; /&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;nbsp; &amp;lt;IocConfiguration unityType=&amp;quot;Project.IoC.EnterpriseLibrary.UnityContainer, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Project.IoC.EnterpriseLibrary&amp;quot; /&amp;gt; &lt;br /&gt;&lt;br /&gt;&amp;lt;/Project&amp;gt;&lt;/p&gt;
&lt;p&gt;y ahora s&amp;iacute;&amp;hellip;&lt;/p&gt;
&lt;code class="prettyprint lang-cs"&gt;
&lt;p&gt;[TestClass] &lt;br /&gt;public class ConfigTest &lt;br /&gt;{&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;[TestMethod] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void TestConfiguration() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var settings = Global.Application.Settings;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.AreEqual(&amp;quot;My Project DDD&amp;quot;, settings.Name); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.AreEqual(&amp;quot;es-ES&amp;quot;, settings.LanguageDefault); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.AreEqual(&amp;quot;dd-MM-yyyy HH:mm&amp;quot;, settings.DateTimeFormat); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.AreEqual(1, settings.TimeZoneOffset); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; [TestMethod] &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void TestIocConfiguration() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var ioc = Global.Application.Ioc; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Assert.IsInstanceOfType(ioc, typeof(Project.IoC.EnterpriseLibrary.UnityContainer)); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;}&lt;/p&gt;
&lt;/code&gt;
&lt;p&gt;Result:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/test_2D00_config_5F00_65235B17.png"&gt;&lt;img height="228" width="497" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/test_2D00_config_5F00_thumb_5F00_0E4AF356.png" alt="test-config" border="0" title="test-config" style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;y Chirrin-chirran&amp;hellip;. &lt;img src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/wlEmoticon_2D00_smile_5F00_3D20D1C5.png" alt="Smile" class="wlEmoticon wlEmoticon-smile" style="border-bottom-style:none;border-left-style:none;border-top-style:none;border-right-style:none;" /&gt;&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=201779" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/omarvr/archive/tags/POO/default.aspx">POO</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/arquitectura/default.aspx">arquitectura</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/NET/default.aspx">NET</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/DDD/default.aspx">DDD</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/IoC/default.aspx">IoC</category></item><item><title>DDD: 2- Framework de IoC (parte 1)</title><link>http://geeks.ms/blogs/omarvr/archive/2011/11/19/ddd-2-framework-de-ioc-parte-1.aspx</link><pubDate>Sat, 19 Nov 2011 08:29:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:201763</guid><dc:creator>Omar del Valle Rodríguez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/rsscomments.aspx?PostID=201763</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/commentapi.aspx?PostID=201763</wfw:comment><comments>http://geeks.ms/blogs/omarvr/archive/2011/11/19/ddd-2-framework-de-ioc-parte-1.aspx#comments</comments><description>&lt;p&gt;&lt;span style="FONT-FAMILY:Calibri;FONT-SIZE:small;"&gt;
&lt;p&gt;&amp;iquest;Por d&amp;oacute;nde empezamos hoy? Pues si conocemos de antemano la arquitectura DDD, sabremos que uno de los aspectos m&amp;aacute;s importante en su implementaci&amp;oacute;n es la inyecci&amp;oacute;n de dependencia. &lt;/p&gt;
&lt;p&gt;El concepto de aplicaciones orientadas al dominio explica claramente que debemos aislar la l&amp;oacute;gica del dominio de cualquier tipo de detalle t&amp;eacute;cnico.&lt;/p&gt;
&lt;p&gt;La &amp;ldquo;Gu&amp;iacute;a de arquitectura N-capas orientada al dominio&amp;rdquo; nos dice&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Esta capa debe ser responsable de representar conceptos de negocio, informaci&amp;oacute;n sobre la situaci&amp;oacute;n de los procesos de negocio e implementaci&amp;oacute;n de las reglas del dominio. Tambi&amp;eacute;n debe contener los estados que refleja n la situaci&amp;oacute;n de los procesos de negocio, aun cuando los detalles t&amp;eacute;cnicos se delegan a las capas inferiores&amp;hellip;.&amp;rdquo;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Resumiendo un poco, el dominio debe saber &amp;ldquo;Qu&amp;eacute;&amp;rdquo; se hace, pero nunca &amp;ldquo;C&amp;oacute;mo&amp;rdquo; se hace&amp;hellip;&lt;/p&gt;
&lt;p&gt;Por otro lado, el concepto de una interfaz es un contrato que indica lo que se debe hacer, pero nunca incluye c&amp;oacute;digo de c&amp;oacute;mo se debe hacer&amp;hellip; De aqu&amp;iacute;, que la forma de aislar el dominio en una arquitectura DDD de su implementaci&amp;oacute;n, sea mediante interfaces.&lt;/p&gt;
&lt;p&gt;La importancia de la inyecci&amp;oacute;n de dependencia en este tipo de arquitectura es precisamente esta, inyectar instancias de objetos que saben &amp;ldquo;c&amp;oacute;mo&amp;rdquo; hacer algo mediante interfaces que indican &amp;ldquo;qu&amp;eacute;&amp;rdquo; se debe hacer.&amp;nbsp; Es l&amp;oacute;gico que los objetos que se inyecten deban implementar la interfaz, pero si no lo hacen ya se encargar&amp;aacute; el framework de avisarnos con un ruidoso error. &lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/4_5F00_3.gif"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/4_5F00_3.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Para usar inyecci&amp;oacute;n de dependencia existen muchos frameworks. Algunos de ellos son:&lt;/p&gt;
&lt;p&gt;-&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Ninject&lt;br /&gt;-&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Unity &lt;br /&gt;-&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Castle.Windsor&lt;br /&gt;-&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Autofac&lt;br /&gt;-&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; StructureMap&lt;/p&gt;
&lt;p&gt;Aqu&amp;iacute; encontraras un buen debate sobre cu&amp;aacute;l es mejor o peor o cu&amp;aacute;les son sus ventajas o desventajas.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://stackoverflow.com/questions/4581791/how-do-the-major-c-sharp-di-ioc-frameworks-compare"&gt;http://stackoverflow.com/questions/4581791/how-do-the-major-c-sharp-di-ioc-frameworks-compare&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A m&amp;iacute; en esta parte siempre me entra la duda, si hablamos de un dominio que no es afectado por los detalles t&amp;eacute;cnicos entonces, &amp;iquest;deber&amp;iacute;a preocuparme por saber cu&amp;aacute;l debe ser el Framework que usar&amp;eacute; para inyectar dependencias? Bueno, tampoco pasemos ol&amp;iacute;mpicamente de esto, claro que deb&amp;iacute;a preocuparme por temas de performance&amp;hellip; pero estos frameworks evolucionan y el que es mejor hoy, ma&amp;ntilde;ana puede ser peor.&lt;/p&gt;
&lt;p&gt;&amp;iquest;Qu&amp;eacute; hago entonces? &amp;iquest;Pues no les gustar&amp;iacute;a poder inyectar a quien te inyecta? &amp;iquest;Nunca han querido pagar con la misma moneda?&amp;nbsp; Yo decid&amp;iacute; inyectar el framework de inyecci&amp;oacute;n&amp;hellip; &lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/imagesCAAD8XIG.jpg"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/imagesCAAD8XIG.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;De lo que hemos visto, el objetivo para m&amp;iacute; de un Framework de inyecci&amp;oacute;n de dependencia es precisamente retornarme una instancia de un objeto mediante su interfaz. Entonces, lo que necesito ser&amp;iacute;a algo como esto:&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint lang-cs"&gt;public interface IContainer &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp; void InitializeContainer(); &lt;br /&gt;&amp;nbsp; T GetInstanceOf&amp;lt;T&amp;gt;(); &lt;br /&gt;&amp;nbsp; T GetInstanceOf&amp;lt;T, TParamType&amp;gt;(TParamType paramInjection); &lt;br /&gt;} &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Ahora necesito alg&amp;uacute;n elemento de configuraci&amp;oacute;n que me indique c&amp;oacute;mo instanciar mi framework de IoC. &amp;iquest;De d&amp;oacute;nde sale la configuraci&amp;oacute;n? Pues no lo s&amp;eacute;, lo que realmente me importa es su contrato, no c&amp;oacute;mo lo haga. La interfaz para la configuraci&amp;oacute;n contiene una propiedad que me retorna el QualifiedName usado para crear el tipo concreto del framework de IoC.&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint lang-cs"&gt;public interface IContainerConfiguration &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp; string IocQualifiedName { get; set; } &lt;br /&gt;&amp;nbsp; Type IocObjectType { get; } &lt;br /&gt;} &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Para combinar el Container con su configuraci&amp;oacute;n nos implementamos un Factory:&lt;/p&gt;
&lt;p&gt;
&lt;div&gt;&lt;code class="prettyprint lang-cs"&gt;public sealed class IocFactory &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp; public IContainer Create(IContainerConfiguration cfg) &lt;br /&gt;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var container = (IContainer)Activator.CreateInstance(cfg.IocObjectType);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; container.InitializeContainer(); &lt;/code&gt;&lt;/div&gt;
&lt;/p&gt;
&lt;code class="prettyprint lang-cs"&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return container;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;} &lt;br /&gt;} &lt;/p&gt;
&lt;/code&gt;
&lt;p&gt;Hasta aqu&amp;iacute; ya tenemos definidas las interfaces&amp;hellip;&amp;nbsp; pero &amp;iquest;qui&amp;eacute;n implementa estas interfaces? y lo m&amp;aacute;s importante, &amp;iquest;c&amp;oacute;mo se usar&amp;iacute;a al final?&lt;/p&gt;
&lt;p&gt;Cada aplicaci&amp;oacute;n que hago, &amp;ldquo;deber&amp;iacute;a&amp;rdquo; tener aspectos que son generales a nivel de toda la aplicaci&amp;oacute;n. Me refiero a par&amp;aacute;metros c&amp;oacute;mo:&lt;/p&gt;
&lt;p&gt;-&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Formato de fecha que usar&amp;eacute; por defecto&lt;br /&gt;-&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Idioma que usar&amp;eacute; por defecto&lt;br /&gt;-&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Zona horaria en que se encuentra la aplicaci&amp;oacute;n&lt;/p&gt;
&lt;p&gt;Estos par&amp;aacute;metros son un poco a mi gusto personal, quiero olvidarme de si el formato de fecha/Hora tiene que ser o no independiente al idioma o si el servidor donde hospedo la aplicaci&amp;oacute;n est&amp;aacute; en Am&amp;eacute;rica o el viejo continente, por eso predefino este tipo de datos. A estos par&amp;aacute;metros se suma ahora mi Framework de IoC, que tambi&amp;eacute;n ser&amp;aacute; de uso general por toda la aplicaci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;C&amp;oacute;mo hemos repetido durante todo el art&amp;iacute;culo, en este punto no s&amp;eacute; de d&amp;oacute;nde saldr&amp;aacute; esta informaci&amp;oacute;n. A algunos les ser&amp;aacute; m&amp;aacute;s &amp;uacute;til sacarlo de base de datos y a otros del archivo de configuraci&amp;oacute;n de la aplicaci&amp;oacute;n, as&amp;iacute; que sigo creando interfaces. &lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/1_5F00_45.gif"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/1_5F00_45.gif" border="0" alt="" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint lang-cs"&gt;public interface IAppConfigurationElement &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp; string Name { get; set; } &lt;br /&gt;&amp;nbsp; string DateTimeFormat { get; set; } &lt;br /&gt;&amp;nbsp; string LanguageDefault { get; set; } &lt;br /&gt;&amp;nbsp; double TimeZoneOffset { get; set; } &lt;br /&gt;} &lt;/code&gt;
&lt;p&gt;Esta interfaz define los par&amp;aacute;metros generales de mi aplicaci&amp;oacute;n. En la siguiente interfaz, combinamos estos par&amp;aacute;metros de configuraci&amp;oacute;n con la interfaz de IoC.&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint lang-cs"&gt;public interface IAppConfigurationSection &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp; IAppConfigurationElement Parameters { get; set; } &lt;br /&gt;&amp;nbsp; IContainerConfiguration Ioc { get; set; } &lt;br /&gt;}&amp;nbsp; &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Finalmente combinamos las interfaces que dar&amp;aacute;n a nuestra aplicaci&amp;oacute;n los par&amp;aacute;metros que hemos definido y el Framework de IoC que usaremos&lt;/p&gt;
&lt;p&gt;&lt;code class="prettyprint lang-cs"&gt;public interface IGlobalSettings &lt;br /&gt;{ &lt;br /&gt;&amp;nbsp; IContainer Ioc { get; } &lt;br /&gt;&amp;nbsp; IAppConfigurationElement Parameters { get; } &lt;br /&gt;} &lt;/code&gt;&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;Con esto mejor cerramos el art&amp;iacute;culo de hoy, creo que me he pasado de largo&amp;nbsp;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/3_5F00_6.gif"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/3_5F00_6.gif" border="0" alt="" /&gt;&lt;/a&gt; as&amp;iacute; que dejamos la implementaci&amp;oacute;n y los test para otro d&amp;iacute;a&amp;hellip;&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;&amp;nbsp;Hasta la pr&amp;oacute;xima... &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=201763" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/omarvr/archive/tags/POO/default.aspx">POO</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/arquitectura/default.aspx">arquitectura</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/DDD/default.aspx">DDD</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/IoC/default.aspx">IoC</category></item><item><title>DDD: 1- Introducción a un esquema genérico…</title><link>http://geeks.ms/blogs/omarvr/archive/2011/11/14/ddd-1-introducci-243-n-a-un-esquema-gen-233-rico.aspx</link><pubDate>Mon, 14 Nov 2011 08:22:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:201685</guid><dc:creator>Omar del Valle Rodríguez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/rsscomments.aspx?PostID=201685</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/commentapi.aspx?PostID=201685</wfw:comment><comments>http://geeks.ms/blogs/omarvr/archive/2011/11/14/ddd-1-introducci-243-n-a-un-esquema-gen-233-rico.aspx#comments</comments><description>&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Me ha costado trabajo decidirme, hay tantos ejemplos de aplicaciones con arquitectura DDD publicados en internet en el que cada uno desarrolla un esquema distinto que uno se piensa una y otra vez si lo que est&amp;aacute; haciendo estar&amp;aacute; bien o ser&amp;aacute; un simple disparate. &lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/9u3y44.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/9u3y44.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Partiendo de esta duda, el objetivo de esta serie no es crear una gu&amp;iacute;a para orquestar una arquitectura DDD, ni siquiera pretendo que sea un modelo a seguir. Mi objetivo es m&amp;aacute;s bien ir compartiendo por aqu&amp;iacute; las cosas que se me van ocurriendo y de ser posible, generar un debate que nos ayude a todos a tener puntos de vista diferentes.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-family:Calibri;"&gt;Sin m&amp;aacute;s, empiezo por donde se empieza cualquier arquitectura&amp;nbsp;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/3_5F00_6.gif"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/3_5F00_6.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-family:Calibri;"&gt; El diagrama de capas:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/DDD.layers.png"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/Untitled.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/Untitled.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Esta parte es la que casi siempre tengo clara&amp;hellip; La distribuci&amp;oacute;n de las capas en Dominio, Aplicaci&amp;oacute;n, Infraestructura, la capa de servicios WCF (opcional) y las interfaces de usuario, cada una con su flujo de informaci&amp;oacute;n.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;No quiero entrar a analizar qu&amp;eacute; va dentro de cada capa porque precisamente la idea es ir comentando el desarrollo que vayamos realizando paso a paso. Solo aclarar que en muchas arquitecturas DDD, puede existir un flujo de informaci&amp;oacute;n entre la interfaz de usuario y el dominio. &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;Este flujo se ve en muchas arquitecturas que muestran inyecci&amp;oacute;n de dependencia de los repositorios dentro de los controladores de un proyecto MVC (incluso ASP.NET MVC est&amp;aacute; preparado para inyectar dependencias a los controladores). En este caso, no vamos a tener ese flujo y es por eso que no lo represento. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;&amp;iquest;Por qu&amp;eacute;? &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Hoy en d&amp;iacute;a es poco habitual que desarrollemos una sola aplicaci&amp;oacute;n, normalmente nuestros proyectos requieren que para un mismo dominio tengamos varios frentes por el que lo atacamos (UI para m&amp;oacute;viles, UI para desktop, servicios que expongan funcionalidad a terceros, etc.). Con el objetivo de centralizar la l&amp;oacute;gica de aplicaci&amp;oacute;n (servicios en la capa aplicaci&amp;oacute;n) y permitir la reutilizaci&amp;oacute;n de c&amp;oacute;digo, es que ninguna interfaz de usuario llega al dominio si no es mediante la capa de aplicaci&amp;oacute;n. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;En Visual Studio cada capa est&amp;aacute; definida como un &amp;ldquo;&lt;strong&gt;Solution Folder&lt;/strong&gt;&amp;rdquo;, por lo que la estructura de mi arquitectura queda m&amp;aacute;s o menos as&amp;iacute;&amp;hellip;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/DDD_2D00_Projects.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/DDD_2D00_Projects.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Creo que se ve que existen 12 proyectos dentro de la soluci&amp;oacute;n, por lo que el desarrollo va mucho m&amp;aacute;s adelantado que esta serie de art&amp;iacute;culos. Espero a medida de que el tiempo me lo permita, ir poni&amp;eacute;ndome al d&amp;iacute;a&amp;hellip;&amp;nbsp;&amp;nbsp;pero sobre todo,&amp;nbsp;espero que se diviertan tanto como yo... &lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/1_5F00_45.gif"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/1_5F00_45.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Salu2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=201685" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/omarvr/archive/tags/patrones+dise_26002300_241_3B00_o+ORM+herencia+arquitectura/default.aspx">patrones dise&amp;#241;o ORM herencia arquitectura</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/POO/default.aspx">POO</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/arquitectura/default.aspx">arquitectura</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/NET/default.aspx">NET</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/ORM/default.aspx">ORM</category></item><item><title>Es la hora del cambio…</title><link>http://geeks.ms/blogs/omarvr/archive/2011/11/08/es-la-hora-del-cambio.aspx</link><pubDate>Tue, 08 Nov 2011 09:53:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:201585</guid><dc:creator>Omar del Valle Rodríguez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/rsscomments.aspx?PostID=201585</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/commentapi.aspx?PostID=201585</wfw:comment><comments>http://geeks.ms/blogs/omarvr/archive/2011/11/08/es-la-hora-del-cambio.aspx#comments</comments><description>&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Primero que todo disculparme si alguien entra en este post pensando que voy a hablar de pol&amp;iacute;tica :P siento que no sea as&amp;iacute;. Ya me sobra con el rega&amp;ntilde;o que me dieron ayer por decir que &amp;ldquo;insidiar&amp;rdquo; era un verbo. ;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Entrando en la materia que nos ocupa&amp;hellip; Muchas veces cuando escuchamos hablar de arquitecturas del tipo DDD, TDD o N capas orientadas al dominio pensamos que todo eso es cosa de unos cuantos frikis que se pasan el d&amp;iacute;a sin nada que hacer e intentando complicarnos la vida y, nada m&amp;aacute;s lejos de la realidad. La arquitectura de un proyecto puede muchas veces llevarnos a escribir un mal c&amp;oacute;digo.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Ayer a un colega le pas&amp;oacute; algo curioso respecto a eso. Introducir una arquitectura orientada al dominio en un grupo de trabajo con apenas experiencia es complicado, la curva de aprendizaje cuando se parte de cero es realmente alta y son muchos los conceptos y paradigmas que nos vemos obligados a cambiar. Entidades, DTO, Inversi&amp;oacute;n de control, Inyecci&amp;oacute;n de dependencias, etc&amp;hellip; todo esto puede ocasionar un retraso en el proyecto que nadie est&amp;aacute; de acuerdo&amp;nbsp;en asumir.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Para evitar todo esto, dise&amp;ntilde;&amp;oacute; una arquitectura N capas de toda la vida con posibilidades de dividirla en niveles, pero a su vez fue insertando conceptos como: Dominio, entidades, DTO, capas, niveles, servicios del dominio, repositorios, etc. toda una base que&amp;nbsp;le permitiera en un momento dado, dar el cambio definitivo a arquitecturas verdaderamente orientadas al dominio.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Ayer se le present&amp;oacute; una problem&amp;aacute;tica, necesitaba mandar a encender desde un panel de administraci&amp;oacute;n un conjunto de dispositivos por un tiempo determinado. Ya ten&amp;iacute;a funcionando toda la l&amp;oacute;gica de encendido y solo deb&amp;iacute;a insertar el nuevo requerimiento de definir el tiempo que dicho dispositivo iba a permanecer encendido.&lt;span style="mso-no-proof:yes;"&gt; &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;La secuencia para encender dispositivos era la siguiente:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/antes.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/antes.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Con el nuevo requerimiento la secuencia qued&amp;oacute; de la siguiente manera:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/despues.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/despues.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;La soluci&amp;oacute;n dada no me gust&amp;oacute; porque rompe con la naturaleza propia del m&amp;eacute;todo, se est&amp;aacute; actualizando estados en un m&amp;eacute;todo destinado a seleccionar. Esto evita que dicho m&amp;eacute;todo pueda ser reutilizado para lo que fue pensado, traer un listado de dispositivos.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span lang="ES" style="line-height:115%;font-family:&amp;#39;Calibri&amp;#39;,&amp;#39;sans-serif&amp;#39;;font-size:11pt;mso-ansi-language:ES;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;mso-hansi-theme-font:minor-latin;mso-bidi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-bidi-theme-font:minor-bidi;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;"&gt;Cuando le dije c&amp;oacute;mo lo hubiera hecho yo, el diagrama de secuencia qued&amp;oacute; de la siguiente forma:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span lang="ES" style="line-height:115%;font-family:&amp;#39;Calibri&amp;#39;,&amp;#39;sans-serif&amp;#39;;font-size:11pt;mso-ansi-language:ES;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;mso-hansi-theme-font:minor-latin;mso-bidi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-bidi-theme-font:minor-bidi;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/propuesta.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/propuesta.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Ummm&amp;hellip; &amp;iquest;Qu&amp;eacute; pasa aqu&amp;iacute;? Yo viajo al dominio mediante los servicios WCF dos veces para realizar una acci&amp;oacute;n. Al final, &amp;eacute;l pens&amp;oacute; una soluci&amp;oacute;n que desde el punto de vista de arquitectura est&amp;aacute; mal, pero es mucho m&amp;aacute;s eficiente que la m&amp;iacute;a.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;&amp;iquest;Por qu&amp;eacute; nos pasa esto? Si miramos el &amp;uacute;ltimo diagrama de secuencia vemos como si algo faltara en la arquitectura que permita hacerlo bien y adem&amp;aacute;s que sea eficiente. Si me llevo esto a DDD &amp;iquest;c&amp;oacute;mo queda?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Diagrama de secuencia:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/DDD.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/DDD.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;span style="font-size:small;"&gt;Feliz y contento&amp;hellip; toda la l&amp;oacute;gica que estaba en el UI ahora pasa a mi capa de aplicaci&amp;oacute;n, por lo que solo viajar&amp;iacute;a una vez por la capa de servicios WCF y todo lo que est&amp;aacute; dentro del ApplicationLayer, podr&amp;iacute;a ser reutilizado desde otros UI.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:small;"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-family:Calibri;"&gt;Nada, que llegamos a la conclusi&amp;oacute;n que&amp;hellip; es la hora del cambio &lt;/span&gt;&lt;/span&gt;&lt;span lang="ES" style="font-family:Wingdings;mso-ansi-language:ES;mso-ascii-theme-font:minor-latin;mso-hansi-theme-font:minor-latin;mso-ascii-font-family:Calibri;mso-hansi-font-family:Calibri;mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;&lt;span style="mso-char-type:symbol;mso-symbol-font-family:Wingdings;"&gt;J&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Salu2&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=201585" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/omarvr/archive/tags/POO/default.aspx">POO</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/arquitectura/default.aspx">arquitectura</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/NET/default.aspx">NET</category></item><item><title>El Daily Stand-Ups (Scrum) ¿Insuficiente?</title><link>http://geeks.ms/blogs/omarvr/archive/2011/11/03/el-daily-stand-ups-scrum-191-insuficiente.aspx</link><pubDate>Thu, 03 Nov 2011 08:27:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:201503</guid><dc:creator>Omar del Valle Rodríguez</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/rsscomments.aspx?PostID=201503</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/commentapi.aspx?PostID=201503</wfw:comment><comments>http://geeks.ms/blogs/omarvr/archive/2011/11/03/el-daily-stand-ups-scrum-191-insuficiente.aspx#comments</comments><description>&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;En el proyecto en el que me encuentro actualmente (equipo de 4 personas) hemos logrado poner en pr&amp;aacute;ctica toda la teor&amp;iacute;a conocida sobre SCRUM. Algunas aplicadas 100% seg&amp;uacute;n la documentaci&amp;oacute;n, otras, adaptadas a los requerimientos del proyecto en s&amp;iacute;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Esto no es nuevo, todos sabemos que la gu&amp;iacute;a para el desarrollo &amp;aacute;gil existe, podemos aprender y usar de ella todo lo que ense&amp;ntilde;a, pero al final&amp;hellip; cada proyecto es un libro aparte que se escribe a su forma y bajo sus propios requerimientos.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Uno de los puntos que no puede faltar (adaptado o no) en un desarrollo &amp;aacute;gil es el Daily Stand-Ups. Esas reuniones de 15 minutos en las que intercambiamos qu&amp;eacute; hacemos, qu&amp;eacute; hemos hecho y qu&amp;eacute; problemas tenemos.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Este tipo de reuni&amp;oacute;n est&amp;aacute; definida en el desarrollo SCRUM de la siguiente manera:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;strong&gt;Daily Stand-Ups (Scrums)&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;During a sprint, the team, the ScrumMaster, &lt;span style="text-decoration:line-through;"&gt;and the product owner&lt;/span&gt; (mejor no invitarle a todas :P ) commit to meeting once daily in the same place and at the same time to discuss any issues that are preventing work from being done. Meetings are held with everyone standing and time boxed to no longer than 15 minutes. Anyone interested is invited to attend these meetings; however, only the people classified as Pigs are allowed to speak at these meetings.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;&amp;nbsp;At the meeting, each team member answers the following three questions:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;&amp;bull; What have you done since yesterday?&lt;br /&gt;&amp;bull; What are you planning to do today?&lt;br /&gt;&amp;bull; Do you have any problems preventing you from accomplishing your goal? What progress has been made on existing impediments? Can the blockage be removed or must it be escalated? (The ScrumMaster looks after this area.)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;
&lt;p class="MsoNormal"&gt;La aplicaci&amp;oacute;n de este tipo de reuniones dentro de un proyecto crea un entorno de trabajo sumamente favorable. Todos conocemos qu&amp;eacute; ha hecho o qu&amp;eacute; est&amp;aacute; haciendo cada miembro del equipo, todos aportamos soluci&amp;oacute;n a los posibles problemas y todos estamos capacitados en un momento dado de asumir una tarea determinada. Los cuellos de botella en un entorno as&amp;iacute;, son detectados muy pronto y permite a su vez, darle una pronta soluci&amp;oacute;n.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;A grandes rasgos, el problema sobre qu&amp;eacute; hace cada miembro del equipo estaba resuelto. Todos &amp;eacute;ramos capaces, sin p&amp;eacute;rdida alguna de tiempo, de asumir o colaborar con la tarea de otro. Pero&amp;hellip; (&lt;strong&gt;&lt;em&gt;Grrrrrr!!!... siempre hay peros&lt;/em&gt;&lt;/strong&gt;) &lt;/p&gt;
&lt;p class="MsoNormal"&gt;Nos dimos cuenta que algo m&amp;aacute;s detallado se nos estaba escapando. Cada tarea asignada a un miembro del equipo normalmente est&amp;aacute; compuesta por Bugs, Tasks, o Issues. La soluci&amp;oacute;n a nivel de c&amp;oacute;digo que se daba a cada elemento muchas veces no contaba con la calidad suficiente, o simplemente no se aplicaba una soluci&amp;oacute;n que pudiera ser reutilizable. A este nivel de detalle en los Daily Stand-ups, no lleg&amp;aacute;bamos.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Una primera soluci&amp;oacute;n fue enviarnos un correo al final del d&amp;iacute;a en el que cada uno cont&amp;aacute;bamos&amp;nbsp; qu&amp;eacute; hab&amp;iacute;a hecho (a nivel de Bugs, Tasks o Issues) hablando un poco de la soluci&amp;oacute;n implementada en cada caso, pero ( y m&amp;aacute;s peros&amp;hellip;) Somos inform&amp;aacute;ticos, odiamos trabajar de m&amp;aacute;s :D&amp;nbsp; y, escribir este correo a final del d&amp;iacute;a iba a terminar perdi&amp;eacute;ndose.&amp;nbsp; &lt;/p&gt;
&lt;p class="MsoNormal"&gt;Pensando un poco en el correo y la informaci&amp;oacute;n que recog&amp;iacute;amos nos dimos cuenta que esto al final era lo mismo que mirar toda la actividad realizada durante el d&amp;iacute;a en el TFS (Team Fundation Server) &amp;iquest;Por qu&amp;eacute; entonces no preguntarle al TFS lo que cada miembro del equipo hab&amp;iacute;a hecho durante el d&amp;iacute;a? Incluso, &amp;iquest;Por qu&amp;eacute; no preguntarle al TFS lo que hab&amp;iacute;a hecho por s&amp;iacute; solo durante el d&amp;iacute;a? (Builds de integraci&amp;oacute;n continua fallidos, Works Items creados, etc.)&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Si pudi&amp;eacute;ramos tener acceso al TFS desde internet, la soluci&amp;oacute;n hubiera sido m&amp;aacute;s simple, pero en la mayor&amp;iacute;a de los casos esto no es as&amp;iacute;. Al final, desarrollamos una tarea que recoge toda la informaci&amp;oacute;n del TFS realizada en el d&amp;iacute;a y nos env&amp;iacute;a&amp;nbsp;un resumen por correo :)&lt;/p&gt;
&lt;p class="MsoNormal"&gt;La soluci&amp;oacute;n nos pareci&amp;oacute; interesante y por si pudiera ser reutilizada por alguien m&amp;aacute;s, la publicaremos ac&amp;aacute; en cuanto le apliquemos un poco de Refactoring y le pongamos una cara bonita.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/TFS_5F00_1.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x441/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/TFS_5F00_1.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/TFS_5F00_1.png"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES" style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/TFS.png"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=201503" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/omarvr/archive/tags/TFS/default.aspx">TFS</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/SCRUM/default.aspx">SCRUM</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/ALM/default.aspx">ALM</category></item><item><title>Evento de ADO.NET con SNUG</title><link>http://geeks.ms/blogs/omarvr/archive/2011/09/12/evento-de-ado-net-con-snug.aspx</link><pubDate>Mon, 12 Sep 2011 06:52:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:200438</guid><dc:creator>Omar del Valle Rodríguez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/rsscomments.aspx?PostID=200438</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/commentapi.aspx?PostID=200438</wfw:comment><comments>http://geeks.ms/blogs/omarvr/archive/2011/09/12/evento-de-ado-net-con-snug.aspx#comments</comments><description>&lt;p&gt;Hola a todos...&lt;/p&gt;
&lt;p&gt;El martes 20 de septiembre, que es el martes pr&amp;oacute;ximo (ma&amp;ntilde;ana no, el pr&amp;oacute;ximo&amp;hellip; o sea&amp;hellip; la semana que viene&amp;hellip; en fin, que me l&amp;iacute;o) :-p, dar&amp;eacute; un evento con los chicos de &lt;a target="_blank" href="http://www.secondnug.com/"&gt;SNUG&lt;/a&gt; sobre ADO.NET&lt;/p&gt;
&lt;p&gt;De ADO.NET hay mucha informaci&amp;oacute;n, libros, eventos, blogs en Internet que contienen material excelente sobre toda la arquitectura, clases, m&amp;eacute;todos, propiedades y eventos que lo componen.&lt;/p&gt;
&lt;p&gt;Para no hacer de este evento uno m&amp;aacute;s de esos tantos, nos vamos a centrar en las buenas pr&amp;aacute;cticas &amp;iquest;&lt;b&gt;qu&amp;eacute; debemos y qu&amp;eacute; no debemos hacer cuando usamos ADO.NET&lt;/b&gt;? Esto no quiere decir que no expliquemos su arquitectura o no vayamos a contar qu&amp;eacute; es un Command, Connection o DataReader, solo que no nos quedaremos ah&amp;iacute;, sino que profundizaremos con ejemplos (Visual Studio 2010 + C#) c&amp;oacute;mo poner en un proyecto real toda esa informaci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;Espero verlos ah&amp;iacute;, y que aprendamos que no solo usando la &amp;uacute;ltima moda como Entity Framework, Linq2Sql o NHibernate, podemos tener buenas pr&amp;aacute;cticas en nuestros desarrollos.&lt;/p&gt;
&lt;p&gt;La URL de registro para el evento es esta: &lt;a target="_blank" href="https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032493902&amp;amp;Culture=es-ES"&gt;https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032493902&amp;amp;Culture=es-ES&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://mseventsww.microsoft.com/BannerImages/70e9f3d4-49e6-46cd-9e17-293ed1dfe403.jpg" style="max-width:550px;" border="0" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;Nos vemos ;)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=200438" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/omarvr/archive/tags/POO/default.aspx">POO</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/arquitectura/default.aspx">arquitectura</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/EF/default.aspx">EF</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/ORM/default.aspx">ORM</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/ADO.NET/default.aspx">ADO.NET</category></item><item><title>resXgen (versión beta)</title><link>http://geeks.ms/blogs/omarvr/archive/2011/07/28/resxgen-versi-243-n-beta.aspx</link><pubDate>Wed, 27 Jul 2011 22:27:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:198385</guid><dc:creator>Omar del Valle Rodríguez</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/rsscomments.aspx?PostID=198385</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/commentapi.aspx?PostID=198385</wfw:comment><comments>http://geeks.ms/blogs/omarvr/archive/2011/07/28/resxgen-versi-243-n-beta.aspx#comments</comments><description>&lt;p&gt;Hola...&lt;/p&gt;
&lt;p&gt;Al fin despu&amp;eacute;s de alg&amp;uacute;n tiempo renovando todo el c&amp;oacute;digo de este proyecto, logro que est&amp;eacute; online.&lt;/p&gt;
&lt;p&gt;La idea surgi&amp;oacute; en un evento de &lt;a target="_blank" href="http://www.secondnug.com"&gt;SNUG&lt;/a&gt; sobre internacionalizaci&amp;oacute;n de aplicaciones en el que se mostr&amp;oacute; una aplicaci&amp;oacute;n que permit&amp;iacute;a leer archivos de recursos (resx). La aplicaci&amp;oacute;n usaba Bing para realizar la traducci&amp;oacute;n a un&amp;nbsp;idioma seleccionado y visualizaba el resultado. (Estaba hecha en Windows Form). &lt;/p&gt;
&lt;p&gt;Al verla, nos gust&amp;oacute; la idea pero llevando su funcionalidad a la WEB. Ya en la WEB, pensamos si no ser&amp;iacute;a mucho m&amp;aacute;s interesante obtener la traducci&amp;oacute;n de Bing y de Google y as&amp;iacute; poder seleccionar de las dos, la m&amp;aacute;s acertada. Aun as&amp;iacute;, algunas traducciones de Google o Bing podr&amp;iacute;an no ser correctas, as&amp;iacute; que decidimos permitir editar la columna de resultados para incluir nuestra propia traducci&amp;oacute;n. Para finalizar, nada m&amp;aacute;s l&amp;oacute;gico que permitir descargar el archivo de recurso ya traducido al idioma seleccionado&amp;hellip; &lt;/p&gt;
&lt;p&gt;As&amp;iacute; surgi&amp;oacute; resXgen &lt;a target="_blank" href="http://resxgen.odelvalle.com/"&gt;http://resxgen.odelvalle.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Hay un bot&amp;oacute;n de&lt;strong&gt; &lt;span style="text-decoration:underline;"&gt;demo&lt;/span&gt;&lt;/strong&gt; que&amp;nbsp; carga un archivo de recurso que tenemos en la aplicaci&amp;oacute;n, de todas maneras, cualquiera puede subir un archivo de recurso, seleccionar el idioma en que se encuentra&amp;nbsp;y probar.&lt;/p&gt;
&lt;p&gt;A&amp;uacute;n est&amp;aacute; en Beta y, entre las cosas m&amp;aacute;s importantes que quedan por hacer, es escribir una ayuda o gu&amp;iacute;a para su utilizaci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;Para reportar cualquier problema o sugerencia he montado un Mantis &lt;a target="_blank" href="http://mantis.odelvalle.com/"&gt;http://mantis.odelvalle.com/&lt;/a&gt; donde podremos darle seguimiento.&lt;/p&gt;
&lt;p&gt;Tratadla suave&amp;nbsp;que a&amp;uacute;n est&amp;aacute;&amp;nbsp; de estreno&amp;hellip;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/3_5F00_6.gif"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/3_5F00_6.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/3za4wwg.gif"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/3za4wwg.gif" border="0" alt="" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=198385" width="1" height="1"&gt;</description></item><item><title>EF 4.1 Code First ¿Dónde está la base de datos?</title><link>http://geeks.ms/blogs/omarvr/archive/2011/07/14/ef-4-1-code-first-191-d-243-nde-est-225-la-base-de-datos.aspx</link><pubDate>Thu, 14 Jul 2011 20:02:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:197775</guid><dc:creator>Omar del Valle Rodríguez</dc:creator><slash:comments>9</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/rsscomments.aspx?PostID=197775</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/commentapi.aspx?PostID=197775</wfw:comment><comments>http://geeks.ms/blogs/omarvr/archive/2011/07/14/ef-4-1-code-first-191-d-243-nde-est-225-la-base-de-datos.aspx#comments</comments><description>&lt;p&gt;Hola&lt;/p&gt;
&lt;p&gt;Me voy a saltar el post pendiente que tengo sobre crear o comentar alg&amp;uacute;n c&amp;oacute;digo existente sobre el algoritmo Hi/Lo para los Object ID en Entity Framework. El culpable de este salto es &lt;a target="_blank" href="http://oscarsotorrio.com/"&gt;un inquieto colega de proyecto&lt;/a&gt; que se puso a probar un art&amp;iacute;culo que publicamos hace unos d&amp;iacute;as por Twitter sobre &lt;a target="_blank" href="http://www.dotnetage.com/publishing/home/2011/07/05/6883/the-repository-pattern-with-ef-code-first-dependeny-injection-in-asp-net-mvc3.html"&gt;MVC 3 con Repositorios e inyecci&amp;oacute;n de dependencias usando Entoty Framework&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;El art&amp;iacute;culo no permite descargar el c&amp;oacute;digo del ejemplo, as&amp;iacute; que, gracias Oscar por ahorrarme el trabajo&amp;nbsp; &lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/6_5F00_iconos_5F00_caritas_5F00_oh_5F00_perdon_5F00_bien_5F00_amor_5F00_payaso.gif"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/6_5F00_iconos_5F00_caritas_5F00_oh_5F00_perdon_5F00_bien_5F00_amor_5F00_payaso.gif" border="0" alt="" /&gt;&lt;/a&gt;&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Despu&amp;eacute;s del pr&amp;oacute;logo y los agradecimientos, entramos en materia. &lt;/p&gt;
&lt;p&gt;El problema, si le podemos llamar as&amp;iacute;, ya lo ten&amp;iacute;a anotado como uno de los temas a tratar en esta nueva aventura con Entity Framework. El c&amp;oacute;digo causante de todo el debate es este:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/imag_2D00_1.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/imag_2D00_1.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;La parte que nos importa en la clase Db, la cual hereda del contexto, es la implementaci&amp;oacute;n del constructor que llama a la base pasando como par&amp;aacute;metro la cadena &amp;ldquo;DemoDb2&amp;rdquo;. El par&amp;aacute;metro que se le pasa al contexto, seg&amp;uacute;n el MSDN, identifica la cadena de conexi&amp;oacute;n o el nombre de la base de datos asociada al modelo que vamos a usar. Este simple c&amp;oacute;digo, si no conoces qu&amp;eacute; hace Entity Framework con &amp;eacute;l, nos puede costar un &amp;ldquo;poquito de dolor de cabeza&amp;rdquo;. &lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/9u3y44.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/9u3y44.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Supongamos que vamos a nuestro archivo de configuraci&amp;oacute;n y definimos la siguiente cadena de conexi&amp;oacute;n (Observe que h&lt;em&gt;e puesto &amp;ldquo;&lt;strong&gt;DemoDb&lt;/strong&gt;&amp;rdquo; y no &amp;ldquo;&lt;strong&gt;DemoDb2&lt;/strong&gt;&amp;rdquo;&lt;/em&gt;)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/imag_2D00_2.png"&gt;&lt;img height="67" width="689" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/imag_2D00_2.png" border="0" style="border:0px;" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;hellip;o simplemente olvidamos que debemos configurar el &lt;strong&gt;web.config&lt;/strong&gt;&amp;nbsp; para indicar la cadena de conexi&amp;oacute;n. Ejecutamos y &amp;ldquo;walaaa&amp;rdquo;&amp;nbsp;&amp;nbsp;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/4_5F00_3.gif"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/4_5F00_3.gif" border="0" alt="" /&gt;&lt;/a&gt;&amp;nbsp; Nuestra aplicaci&amp;oacute;n funciona&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/imag_2D00_3.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/imag_2D00_3.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Si voy a mi servidor&amp;nbsp;en busca de&amp;nbsp;la base de datos me encuentro con que no existe. Pues bien, si EF no encuentra la cadena de conexi&amp;oacute;n o la misma es incorrecta, utiliza el SQL Express que tengamos instalado en local y con autenticaci&amp;oacute;n integrada de Windows, crea la base de datos.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/imag_2D00_4.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/imag_2D00_4.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;span style="text-decoration:line-through;"&gt;Les juro que no estoy haciendo trampas, ninguna de las bases de datos que est&amp;aacute;n tachadas es la del ejemplo&lt;/span&gt;&lt;/em&gt;&amp;nbsp; &lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/1_5F00_45.gif"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/1_5F00_45.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;En mi opini&amp;oacute;n, hubiera preferido que ocurriera un error y as&amp;iacute; darme cuenta que ten&amp;iacute;a algo mal, digamos que algo as&amp;iacute;...&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/imag_2D00_5.png"&gt;&lt;img height="253" width="760" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/imag_2D00_5.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/3za4wwg.gif"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/3za4wwg.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;strong&gt;&lt;em&gt;Editado&lt;/em&gt;&lt;/strong&gt;: &lt;em&gt;En los comentarios,&amp;nbsp;&lt;/em&gt;&lt;a href="http://geeks.ms/user/Profile.aspx?UserID=10177" title="Pablo N&amp;uacute;&amp;ntilde;ez"&gt;&lt;span style="color:#006ff7;"&gt;&lt;em&gt;Pablo N&amp;uacute;&amp;ntilde;ez&lt;/em&gt;&lt;/span&gt;&lt;/a&gt;&lt;em&gt;&amp;nbsp; nos dice c&amp;oacute;mo lograr que EF pueda tener el mismo comportamiento que NH. (Gracias Pablo)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=197775" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/omarvr/archive/tags/mvc/default.aspx">mvc</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/arquitectura/default.aspx">arquitectura</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/NET/default.aspx">NET</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/EF/default.aspx">EF</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/ORM/default.aspx">ORM</category></item><item><title>Object ID en EF 4.1</title><link>http://geeks.ms/blogs/omarvr/archive/2011/07/06/object-id-en-ef-4-1.aspx</link><pubDate>Tue, 05 Jul 2011 22:24:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:197268</guid><dc:creator>Omar del Valle Rodríguez</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/rsscomments.aspx?PostID=197268</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/commentapi.aspx?PostID=197268</wfw:comment><comments>http://geeks.ms/blogs/omarvr/archive/2011/07/06/object-id-en-ef-4-1.aspx#comments</comments><description>&lt;p&gt;Hola&lt;/p&gt;
&lt;p&gt;Hace poco me he comprado el excelente &lt;a target="_blank" href="http://geeks.ms/blogs/unai/archive/2011/05/16/libro-ado-net-ef-4-1.aspx"&gt;libro de Entity Framework 4.1&lt;/a&gt;. He le&amp;iacute;do mucho sobre este ORM desde sus primeras versiones, pero nunca me result&amp;oacute; lo suficientemente atractivo para usar en un proyecto real sobre el cual me permitieran elegir. Como alternativa a EF ten&amp;iacute;a NHibernate, ORM que tambi&amp;eacute;n he usado desde hace mucho tiempo y sobre el cual no tengo dudas en cuanto a funcionalidad o&amp;nbsp;limitaciones que me pueda encontrar. &lt;/p&gt;
&lt;p&gt;Entendiendo que no siempre se puede elegir, y por los muchos comentarios que ha generado la nueva versi&amp;oacute;n de EF 4.1 (y m&amp;aacute;s por la posibilidad real de no tener atadas las entidades al ORM) decid&amp;iacute; de una vez enfrentarme a &amp;eacute;l de manera seria, pero es inevitable hacer comparaciones (aunque no sean buenas)&amp;nbsp; &lt;/p&gt;
&lt;p&gt;Aclaro que mi intenci&amp;oacute;n jam&amp;aacute;s ser&amp;iacute;a, ni por asomo, criticar a este excelente ORM, m&amp;aacute;s bien esta serie de art&amp;iacute;culos va por el camino de conocer bien hasta d&amp;oacute;nde llegan&amp;nbsp;mis limitaciones en su utilizaci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Los Object ID&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Desde cualquier aplicaci&amp;oacute;n orientada al dominio se enfoca mucho la necesidad, que yo llamar&amp;iacute;a obligaci&amp;oacute;n, de empezar siempre por el modelo. Es imposible no acordarme de la forma en que casi se suplica en el libro de EF 4.1 (P&amp;aacute;g. 78) cuando dice: &amp;ndash; &amp;ldquo;&lt;em&gt;Primero el modelo por favor&lt;/em&gt;&amp;rdquo;.&amp;nbsp;&lt;strong&gt; :)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Siguiendo tan buen consejo me voy a Visual Studio dispuesto a seguir el ejemplo descrito en el libro empezando por la entidad&amp;nbsp; &amp;ldquo;Autor&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/Image_2D00_1.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/Image_2D00_1.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Me detengo en esta ventana en la que remarco la propiedad &amp;ldquo;Key Property&amp;rdquo;. &amp;iquest;Qu&amp;eacute; significa esto desde el punto de vista del modelo? Pues si estoy pensando en el modelo esta propiedad representa entonces el Object ID de la entidad.&lt;/p&gt;
&lt;p&gt;La definici&amp;oacute;n de Object ID est&amp;aacute; explicada en Mapping Objects To Relational Databases de Scott W. Amble.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;&lt;em&gt;We need to assign unique identifiers to our objects so that we can identify them. In relational terminology a unique identifier is called a key, in object terminology it is called an object identifier (OID) although perhaps persistent object identifier would be a better term. OIDs are typically implemented as full-fledged objects in your OO applications and as large integers, or several large integers for larger applications, in your relational schema&lt;/em&gt;&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Yo creo que la definici&amp;oacute;n ni siquiera necesita traducci&amp;oacute;n&amp;nbsp;&lt;strong&gt;:)&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;Algunas funcionalidades de los OID coinciden con su &amp;ldquo;hom&amp;oacute;logo&amp;rdquo; en el modelo relacional. Por ejemplo, mantener y simplificar la relaci&amp;oacute;n entre entidades (joins entre tablas en el modelo relacional).&amp;nbsp;Uno de los errores m&amp;aacute;s comunes cuando definimos el modelo es cuando asignamos una responsabilidad al OID dentro del dominio. Los OID &lt;strong&gt;NO&lt;/strong&gt; pueden tener ning&amp;uacute;n significado l&amp;oacute;gico&amp;nbsp;&amp;ldquo;Nada, Zip, Zilch, Zero&amp;rdquo;&amp;nbsp; &lt;strong&gt;:P&lt;/strong&gt; Como dice Scott, toda propiedad que interviene en un modelo con un significado dentro del dominio puede ser potencialmente cambiada. Un OID, no.&lt;/p&gt;
&lt;p&gt;Regresando a EF 4.1 (que me pierdo) creo mi entidad y me decido a seleccionar mi estrategia para el OID dentro del modelo.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/Image_2D00_2.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/Image_2D00_2.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Pues vaya sorpresa&amp;nbsp;&lt;strong&gt;:&amp;quot;(&lt;/strong&gt; solo tengo 3 opciones como estrategia para generar mi OID. &amp;iquest;Cu&amp;aacute;l de estas tres opciones puedo elegir?&lt;/p&gt;
&lt;p&gt;MSDN dice:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Computed&lt;/strong&gt; -&amp;nbsp;Un valor generado para INSERT y para UPDATE.&amp;nbsp;o_0&amp;nbsp; No me he puesto a pensar en qu&amp;eacute; casos me puede ser &amp;uacute;til esta estrategia, ahora mismo no me imagino ninguna porque si el OID cambia durante su ciclo de vida, rompe con su condici&amp;oacute;n de ser &amp;uacute;nico e invariable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Identity&lt;/strong&gt; - Un valor que es generado durante el INSERT y que permanece invariable durante las actualizaciones siguientes. Esto es un Identity de SQL en toda regla. &amp;iquest;Por qu&amp;eacute; el identity de SQL no es para m&amp;iacute; una estrategia v&amp;aacute;lida? Pues Scott lo deja claro cuando dice &amp;ldquo;An OID should be unique within a class hierarchy, and ideally unique among all objects&amp;rdquo;&lt;/p&gt;
&lt;p&gt;El identity puede generar un mismo valor dentro del modelo para dos entidades distintas y esto romper&amp;iacute;a tambi&amp;eacute;n con la definici&amp;oacute;n &amp;ldquo;ideal&amp;rdquo; del OID, adem&amp;aacute;s, no me vale en absoluto en un sistema distribuido (en un clusters por ejemplo).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;None&lt;/strong&gt; - Generarlo yo implica que tenga que pelearme con el bloqueo de filas para evitar que dos clientes de mi sistema no generen al mismo tiempo un mismo OID. Resultar&amp;iacute;a tan complejo como se pueda imaginar. Aunque ser&amp;iacute;a la &amp;uacute;nica alternativa y por suerte, hay algoritmos que nos permiten no entrar en pol&amp;eacute;micas con los bloqueos&lt;/p&gt;
&lt;p&gt;NHibernate por su parte propone para los OID&amp;nbsp;las siguientes&amp;nbsp;estrategias : Increment, identity, sequence, hilo(&lt;strong&gt;Mi Favorito&lt;/strong&gt;), seqhilo, uuid.hex, uuid.string, guid, guid.comb, native, assigned y foreign. Las puedes encontrar todas explicadas &lt;a target="_blank" href="http://www.nhforge.org/doc/nh/en/index.html#mapping-declaration-id"&gt;aqu&amp;iacute;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Hay que tener en cuenta que NHibernate y EF, trabajan de manera distinta respecto a los OID. NH asegura que se pueda trabajar con el OID de una entidad antes de hacer permanentes los cambios en base de datos, algo muy importante cuando usamos Session per request. Por su parte, EF asegura la unidad dentro del contexto, por lo que no dar&amp;aacute; el OID hasta que no se guarden los cambios (Si no lo generamos nosotros).&lt;/p&gt;
&lt;p&gt;Mi pr&amp;oacute;ximo paso en esta serie ser&amp;aacute; ver si puedo crear una estrategia Hi/Lo para usar en EF. La idea del algoritmo Hi/Lo es tener dos valores para formar un &amp;uacute;nico valor. A cada cliente se le asigna un valor Hi y, con un rango de valores Low formar&amp;iacute;a un identificador &amp;uacute;nico para todo el modelo. Esto garantiza que varios clientes siempre utlizar&amp;aacute;n valores distintos para los nuevos OID creados y evitar&amp;iacute;amos los temas de bloqueos. &lt;/p&gt;
&lt;p&gt;&amp;iquest;c&amp;oacute;mo resuelven esta &amp;quot;limitaci&amp;oacute;n&amp;quot;&amp;nbsp;cada uno de&amp;nbsp;los que actualmente usan EF?&amp;nbsp;&amp;nbsp;;)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=197268" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/omarvr/archive/tags/patrones+dise_26002300_241_3B00_o+ORM+herencia+arquitectura/default.aspx">patrones dise&amp;#241;o ORM herencia arquitectura</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/POO/default.aspx">POO</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/arquitectura/default.aspx">arquitectura</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/NET/default.aspx">NET</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/EF/default.aspx">EF</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/ORM/default.aspx">ORM</category></item><item><title>Patrón Iterator</title><link>http://geeks.ms/blogs/omarvr/archive/2011/06/26/patr-243-n-iterator.aspx</link><pubDate>Sun, 26 Jun 2011 10:41:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:196643</guid><dc:creator>Omar del Valle Rodríguez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/rsscomments.aspx?PostID=196643</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/commentapi.aspx?PostID=196643</wfw:comment><comments>http://geeks.ms/blogs/omarvr/archive/2011/06/26/patr-243-n-iterator.aspx#comments</comments><description>&lt;p&gt;Hola de nuevo, hoy ando de nost&amp;aacute;lgico revisando &amp;quot;viejos&amp;quot; documentos :)&lt;/p&gt;
&lt;p&gt;Este es uno de los que m&amp;aacute;s me gusta... Patr&amp;oacute;n iterator, creado al igual que el anterior para el mismo curso de patrones. Les dejo el documento adjunto.&lt;/p&gt;
&lt;p&gt;Salu2&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=196643" width="1" height="1"&gt;</description><enclosure url="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.19.66.43/Iterator-Pattern_2D00_geeks.doc" length="151040" type="application/msword" /><category domain="http://geeks.ms/blogs/omarvr/archive/tags/patrones+dise_26002300_241_3B00_o+ORM+herencia+arquitectura/default.aspx">patrones dise&amp;#241;o ORM herencia arquitectura</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/POO/default.aspx">POO</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/arquitectura/default.aspx">arquitectura</category></item><item><title>Patrón Command</title><link>http://geeks.ms/blogs/omarvr/archive/2011/06/26/patr-243-n-command.aspx</link><pubDate>Sun, 26 Jun 2011 10:02:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:196642</guid><dc:creator>Omar del Valle Rodríguez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/rsscomments.aspx?PostID=196642</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/commentapi.aspx?PostID=196642</wfw:comment><comments>http://geeks.ms/blogs/omarvr/archive/2011/06/26/patr-243-n-command.aspx#comments</comments><description>&lt;p&gt;Hola,&lt;/p&gt;
&lt;p&gt;Hoy en d&amp;iacute;a, en muchas de las arquitecturas de moda escuchamos hablar de un patr&amp;oacute;n muy utilizado llamado &amp;quot;Command&amp;quot;.&amp;nbsp; &amp;iquest;Sabemos con claridad lo que es el patr&amp;oacute;n Command? &lt;/p&gt;
&lt;p&gt;Para quien a&amp;uacute;n no lo tenga tan claro les dejo un documento creado para un curso de patrones en el MUG de Argentina en el a&amp;ntilde;o 2004. Espero les ayude a entender un poquito m&amp;aacute;s a este excelente y tan utilizado patr&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;Salu2&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=196642" width="1" height="1"&gt;</description><enclosure url="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Components.PostAttachments/00.00.19.66.42/command_2D00_geeks.doc" length="181760" type="application/octet-stream" /><category domain="http://geeks.ms/blogs/omarvr/archive/tags/patrones+dise_26002300_241_3B00_o+ORM+herencia+arquitectura/default.aspx">patrones dise&amp;#241;o ORM herencia arquitectura</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/POO/default.aspx">POO</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/arquitectura/default.aspx">arquitectura</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/NET/default.aspx">NET</category></item><item><title>Las consecuencias de trabajar mal…</title><link>http://geeks.ms/blogs/omarvr/archive/2011/04/23/las-consecuencias-de-trabajar-mal.aspx</link><pubDate>Fri, 22 Apr 2011 22:34:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:192790</guid><dc:creator>Omar del Valle Rodríguez</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/rsscomments.aspx?PostID=192790</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/commentapi.aspx?PostID=192790</wfw:comment><comments>http://geeks.ms/blogs/omarvr/archive/2011/04/23/las-consecuencias-de-trabajar-mal.aspx#comments</comments><description>&lt;p&gt;En estos d&amp;iacute;as parece haber un BOM de an&amp;aacute;lisis sobre pruebas unitarias, sobre metodolog&amp;iacute;as, sobre si hago bien o no en hacer las cosas como se deben hacer, el tiempo que ahorro o el tiempo que pierdo, etc. etc. etc. La historia que me dispongo a contarles es real, as&amp;iacute; que como ya es costumbre en estos casos no se puede hacer menci&amp;oacute;n de nombres de empresas o detalles del proyecto. Bueno, me chivo un poco: X no es espa&amp;ntilde;ola... :)&lt;br /&gt;&lt;br /&gt;Llegamos al cliente con un objetivo. Se estaba preparando una demo por una empresa X sobre un conjunto de servicios novedosos que podr&amp;iacute;an ser implementados o llevados a la realidad en un futuro cercano. Aquello era una DEMO guiada, por lo que solo una persona que conoc&amp;iacute;a todo el gui&amp;oacute;n interactuaba con los sistemas, adem&amp;aacute;s, el objetivo de la empresa X era vender la idea, pero en ning&amp;uacute;n caso llevar dicho proyecto a un entorno interactivo o permitir que aquello sirviera de base para continuar posibles desarrollos de ideas. Aqu&amp;iacute; entrabamos nosotros.&lt;br /&gt;&lt;br /&gt;Nuestra tarea era ir implementando un entorno organizado de todo lo que la empresa X realizaba, llevarlo a un modelo interactivo donde cualquiera pudiera interactuar con el sistema o en donde se pudieran realizar desarrollos a futuro usando de base todo lo que ya exist&amp;iacute;a.&lt;br /&gt;&lt;br /&gt;La empresa X con su idea clara de DEMO guiada, opt&amp;oacute; por el siguiente modelo de desarrollo.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/img1.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/img1.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Sin muchas complicaciones. Ten&amp;iacute;an m&amp;uacute;ltiples funcionalidades concentradas en una misma aplicaci&amp;oacute;n WEB construidas sobre MVC. Para cada funcionalidad ten&amp;iacute;an un &amp;uacute;nico controlador desde el que interactuaban con la base de datos (donde fuera necesario) usando directamente linq2sql.&lt;br /&gt;&lt;br /&gt;Nuestro objetivo estaba bien marcado, cambiar todo eso y convertirlo en algo sostenible desde el punto de vista de arquitectura, pero &amp;iquest;era suficiente? El reconocimiento del trabajo realizado es la base de cualquier cosa que se desee que salga bien, pero en un proyecto como este &amp;iquest;qu&amp;eacute; se pod&amp;iacute;a hacer?&lt;br /&gt;&lt;br /&gt;Ten&amp;iacute;amos los siguientes problemas:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Los requerimientos se les ped&amp;iacute;an directamente a la empresa X&lt;/li&gt;
&lt;li&gt;La empresa X siempre iba a estar evolucionando la DEMO con los nuevos requerimientos&lt;/li&gt;
&lt;li&gt;Mientras no finalizara la DEMO, nuestro trabajo iba a estar en un segundo plano. :&amp;#39;(&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Ni estar en un segundo plano, ni secundar la estrategia de otros (si no es correcta), es una idea que nos agrada en estos casos, m&amp;aacute;s si se trata de tu primer trabajo a un cliente importante. Hab&amp;iacute;a que lograr algo m&amp;aacute;s&amp;hellip;&lt;/p&gt;
&lt;p&gt;Los problemas que pod&amp;iacute;an tener los desarrolladores de la empresa X eran evidentes.&amp;nbsp; Esos mismos problemas que tan com&amp;uacute;nmente nos cuestionamos por estos tiempos. No quieren perder tiempo y desarrollan algo que es solo para mostrar, as&amp;iacute; que van a toda prisa y se olvidan que sea lo que sea que se construya, si no lo levantas desde una base s&amp;oacute;lida llegar&amp;aacute; el momento en que se convierta en algo insostenible.&lt;br /&gt;&lt;br /&gt;En una pancarta de publicidad, por poner un ejemplo, el objetivo puede ser solamente mostrar un pedazo de papel. Si usas solo los materiales que permitan mantener en pie la pancarta sin poder ver otros requerimientos a medio y largo plazo, cuando te pidan colocar luminaria sobre la pancarta para que pueda ser vista de noche, tendr&amp;aacute;s que regresar a la base y apuntalar todo lo que hab&amp;iacute;as hecho para luego poder colocar las luces.&lt;br /&gt;&lt;br /&gt;Con este an&amp;aacute;lisis realizado nos trazamos un objetivo m&amp;aacute;s ambicioso:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Crear un entorno &amp;aacute;gil de desarrollo: Esto era indispensable, necesit&amp;aacute;bamos trabajar r&amp;aacute;pido y con ciclos cortos de evoluci&amp;oacute;n. Todos deb&amp;iacute;amos conocer el trabajo de todos y los cuellos de botella que pudieran afectar el ritmo que dese&amp;aacute;bamos llevar, deb&amp;iacute;an ser resueltos de inmediato.&amp;nbsp; (Reuniones en la m&amp;aacute;quina del caf&amp;eacute; de 15 min hasta tres veces al d&amp;iacute;a)&amp;nbsp; :P&lt;/li&gt;
&lt;li&gt;Una arquitectura organizada que nos permitiera identificar r&amp;aacute;pidamente los problemas y solucionarlos afectando el menor c&amp;oacute;digo posible. Esto a su vez nos llevar&amp;aacute; a que aplicar nuevos requerimientos sea sencillo y r&amp;aacute;pido de realizar. Con este objetivo separamos todas las funcionalidades en aplicaciones distintas pero manteniendo MVC y, creamos servicios WCF para cada aplicaci&amp;oacute;n. Los servicios WCF se comunicaban con un dominio &amp;uacute;nico que nos permit&amp;iacute;a desde las distintas aplicaciones, reutilizar la l&amp;oacute;gica de desarrollada. (Una simple arquitectura de N capas)&lt;/li&gt;
&lt;li&gt;Mejoras de performance donde quiera que fuera posible. Este objetivo era menor, pero donde pudi&amp;eacute;ramos, deb&amp;iacute;amos hacerlo. El efecto visual es importante de cara a cualquier cliente y muchas veces se trata solamente de variar el orden en que hacemos las cosas.&lt;/li&gt;
&lt;li&gt;Integraci&amp;oacute;n continua y test unitarios (todo y en todo momento, deb&amp;iacute;a funcionar bien).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;La arquitectura (a grandes rasgos) que nos propusimos fue la siguiente:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/img2.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/img2.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;En principio estar en segundo plano era inevitable. Deb&amp;iacute;amos estar constantemente chequeando la DEMO para ver las nuevas evoluciones e implementar los cambios sobre nuestra arquitectura pero de manera correcta. Solo pod&amp;iacute;amos trabajar r&amp;aacute;pido y bien, el resto era simplemente esperar, darle tiempo al tiempo.&lt;br /&gt;&lt;br /&gt;&amp;hellip;y el tiempo pas&amp;oacute;, y lleg&amp;oacute; lo que muchos no somos capaces de ver desde un principio. El cambio&amp;hellip; Porque siempre, siempre hay cambios... &lt;br /&gt;&lt;br /&gt;Aqu&amp;iacute; cometieron un nuevo error, pero que es muy com&amp;uacute;n en los desarrollos que hacemos a diario. Se pidieron cambios funcionales sobre un proceso determinado pero, realizar las modificaciones sobre lo que ya estaba hecho empezaba a ocupar tiempo y era justo lo que no hab&amp;iacute;a. No le puedes decir a un cliente que te demoras 1 mes en&amp;nbsp; hacer un cambio. Entonces, &amp;iquest;qu&amp;eacute; hicieron? La soluci&amp;oacute;n fue crear un camino nuevo para dar una respuesta r&amp;aacute;pida a los cambios. (copy + paste + hacer los cambios) Otra bomba por culpa del tiempo...&lt;br /&gt;&lt;br /&gt;Pas&amp;oacute; que los cambios no quedaron ah&amp;iacute;, y vinieron m&amp;aacute;s y m&amp;aacute;s y se opt&amp;oacute; por hacer de cada cambio un camino nuevo que cumpliera los requerimientos. El final a esto es previsible, nada cuadraba con nada. Lo que se mostraba en un lugar no ten&amp;iacute;a que ver con lo que se mostraba en otro. Modificabas algo en un lugar y no se reflejaba en otro. Lograr entonces que el sistema fuera coherente, implicaba modificar todos los nuevos caminos abiertos para los nuevos requerimientos. Cada cambio que se ped&amp;iacute;a, demoraba m&amp;aacute;s y m&amp;aacute;s y m&amp;aacute;s&amp;hellip;&lt;br /&gt;&lt;br /&gt;Y mientras del otro lado de la monta&amp;ntilde;a... :)&amp;nbsp; El tiempo nos sirvi&amp;oacute; para lograr dos cosas:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Llegar a igualar nuestra funcionalidad a la que ten&amp;iacute;a la empresa X hasta el momento.&lt;/li&gt;
&lt;li&gt;Indagar sobre nuevas funcionalidades que no estaban incluidas en la DEMO y desarrollarlas&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Al presentar por primera vez nuestro trabajo nos hicieron algunas observaciones y nos pidieron algunos cambios. La respuesta a todos los cambios era un s&amp;iacute;. El tiempo para realizarlos 4 d&amp;iacute;as. Era lunes, el viernes se deb&amp;iacute;an presentar para revisi&amp;oacute;n&amp;hellip;&lt;/p&gt;
&lt;p&gt;La demo guiada que hoy se usa, es nuestra aplicaci&amp;oacute;n. :)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Pero, pero, pero...&lt;/b&gt; no escribo todo esto para decir que lo hemos hecho mejor. Estoy seguro que a muchos de ustedes se les ocurrir&amp;iacute;an estrategias mejores que la que nos planteamos. Lo dejo escrito, y de ah&amp;iacute; el t&amp;iacute;tulo de este post, para que vean que todo cuanto hacen, por muy DEMO que sea, si no se hace m&amp;iacute;nimamente bien, a la larga se convierte en una bomba de tiempo contra nosotros mismos. El tiempo que crees ahorrar en un principio no haciendo test, pensando en arquitecturas o so&amp;ntilde;ando con metodolog&amp;iacute;as, puede ser el peor enemigo de lo que est&amp;aacute;s haciendo.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;Salu2 y suerte con las DEMO... ;)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=192790" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/omarvr/archive/tags/arquitectura/default.aspx">arquitectura</category></item><item><title>Publica en Twitter desde el safari del iPhone</title><link>http://geeks.ms/blogs/omarvr/archive/2011/03/18/publica-en-tweeter-desde-safary.aspx</link><pubDate>Fri, 18 Mar 2011 09:46:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:190630</guid><dc:creator>Omar del Valle Rodríguez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/rsscomments.aspx?PostID=190630</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/commentapi.aspx?PostID=190630</wfw:comment><comments>http://geeks.ms/blogs/omarvr/archive/2011/03/18/publica-en-tweeter-desde-safary.aspx#comments</comments><description>&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Hola,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Hoy ando de inventos&amp;hellip; &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Resulta que me he instalado la aplicaci&amp;oacute;n de &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Twitter &lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;para iPhone porque hace mucho tengo una cuenta en esta red social, pero tambi&amp;eacute;n hace mucho que la ten&amp;iacute;a abandonada.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Mirando la aplicaci&amp;oacute;n echaba mucho en falta el poder publicar URL directamente desde el navegador del iPhone, pero buscando y buscando me encontr&amp;eacute; que en los settings de la aplicaci&amp;oacute;n para &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Twitter &lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;hab&amp;iacute;a una forma de hacer lo que quer&amp;iacute;a.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Las instrucciones a seguir est&amp;aacute;n en esta p&amp;aacute;gina:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;a href="http://www.atebits.com/___"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/atebits.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Era crear un simple bookmark y luego editarlo para dejar solo el javascript. Esto estaba genial pero&amp;hellip; las URL las publicaba a tama&amp;ntilde;o completo y esto para una red que solo permite 140 caracteres por post, es realmente un problema.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Mirando la forma en que lo hac&amp;iacute;an me di cuenta que lo que hacen es usar javascript para llamar a la aplicaci&amp;oacute;n de &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Twitter &lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;y le pasan el URL actual, o sea, el window.location.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;La pregunta del mill&amp;oacute;n era: &amp;iquest;Qu&amp;eacute; pasa si antes de llamar a tweetie tomo la URL, la convierto &lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&lt;/span&gt;a un formato peque&amp;ntilde;o (por ejemplo: tinyUrl) y luego se la paso a la aplicaci&amp;oacute;n de &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Twitter&lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;? &amp;iquest;C&amp;oacute;mo podr&amp;iacute;a hacer algo as&amp;iacute;?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Pues bien&amp;hellip; me frot&amp;eacute; las manos y empec&amp;eacute;: &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Me creo una p&amp;aacute;gina HTML sin m&amp;aacute;s, incluyo una referencia a Jquery desde el CDN de Microsoft, y con jQuery en mano, todo es f&amp;aacute;cil :))))) &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Mi p&amp;aacute;gina debe:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;1- Tomar un par&amp;aacute;metro que le pasar&amp;iacute;an, el cual ser&amp;iacute;a el URL en el que se encuentra navegando el usuario&lt;br /&gt;2- &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;De alguna forma usar el servicio de TinyURL para convertir la URL a un formato peque&amp;ntilde;o&lt;br /&gt;3- &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;y finalmente pasar el resultado a &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Twitter&lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;&amp;iquest;Parece simple no? &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Aqu&amp;iacute; est&amp;aacute; el c&amp;oacute;digo:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div class="source-code"&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-family:Consolas;color:blue;font-size:9.5pt;mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family:Consolas;color:maroon;font-size:9.5pt;mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;html&lt;/span&gt;&lt;span style="font-family:Consolas;color:blue;font-size:9.5pt;mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;color:blue;font-size:9.5pt;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family:Consolas;color:maroon;font-size:9.5pt;"&gt;head&lt;/span&gt;&lt;span style="font-family:Consolas;color:blue;font-size:9.5pt;"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:9.5pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;script&lt;/span&gt; &lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;text/javascript&amp;quot;&lt;/span&gt; &lt;span style="color:red;"&gt;src&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;http://ajax.microsoft.com/ajax/jQuery/jquery-1.5.1.min.js&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;script&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:9.5pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;script&lt;/span&gt; &lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:9.5pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;function&lt;/span&gt; makeTinyUrl(url)&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:9.5pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:9.5pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;$.getJSON(&lt;span style="color:maroon;"&gt;&amp;#39;http://json-tinyurl.appspot.com/?url=&amp;#39;&lt;/span&gt; + url + &lt;span style="color:maroon;"&gt;&amp;#39;&amp;amp;callback=?&amp;#39;&lt;/span&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:9.5pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;function&lt;/span&gt; (data)&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:9.5pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:9.5pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;window.location = &lt;span style="color:maroon;"&gt;&amp;#39;tweetie:&amp;#39;&lt;/span&gt; + data.tinyurl;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:9.5pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;});&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:9.5pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-family:Consolas;font-size:9.5pt;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-family:Consolas;font-size:9.5pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; urlParams = {};&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:9.5pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; e,&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:9.5pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;a = /\+/g,&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:darkgreen;"&gt;// Regex for replacing addition symbol with a space&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:9.5pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;r = /([^&amp;amp;=]+)=?([^&amp;amp;]*)/g,&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:9.5pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;d = &lt;span style="color:blue;"&gt;function&lt;/span&gt; (s) { &lt;span style="color:blue;"&gt;return&lt;/span&gt; decodeURIComponent(s.replace(a, &lt;span style="color:maroon;"&gt;&amp;quot; &amp;quot;&lt;/span&gt;)); },&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:9.5pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;q = window.location.search.substring(1);&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-family:Consolas;font-size:9.5pt;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-family:Consolas;font-size:9.5pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;color:blue;font-size:9.5pt;mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;while&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:9.5pt;mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt; (e = r.exec(q)) urlParams[d(e[1])] = d(e[2]);&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-family:Consolas;font-size:9.5pt;mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-family:Consolas;font-size:9.5pt;mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;font-size:9.5pt;"&gt;makeTinyUrl(urlParams[&lt;span style="color:maroon;"&gt;&amp;#39;tw&amp;#39;&lt;/span&gt;]);&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-family:Consolas;font-size:9.5pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-family:Consolas;font-size:9.5pt;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;script&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-family:Consolas;color:blue;font-size:9.5pt;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-family:Consolas;color:maroon;font-size:9.5pt;"&gt;head&lt;/span&gt;&lt;span style="font-family:Consolas;color:blue;font-size:9.5pt;"&gt;&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;color:blue;font-size:9.5pt;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family:Consolas;color:maroon;font-size:9.5pt;"&gt;body&lt;/span&gt;&lt;span style="font-family:Consolas;color:blue;font-size:9.5pt;"&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Consolas;color:blue;font-size:9.5pt;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-family:Consolas;color:maroon;font-size:9.5pt;"&gt;html&lt;/span&gt;&lt;span style="font-family:Consolas;color:blue;font-size:9.5pt;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Despu&amp;eacute;s de publicar mi p&amp;aacute;gina HTML en un servidor,&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;el resto era f&amp;aacute;cil: Seguir los mismos pasos que dan en Atebits y probar&amp;hellip; :)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Me cree un bookmark en el safari del iPhone con la siguiente URL:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/sinportales.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/sinportales.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-family:Calibri;font-size:small;"&gt;y WALAAAA!!! Funciona!! :)))))&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Quiero aclarar que esta URL solo la dejar&amp;eacute; publica por un tiempo para que puedan probar, pero de ninguna forma es parte o se trata de un servicio p&amp;uacute;blico.&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-family:Calibri;font-size:small;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Salu2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES-TRAD;" lang="ES-TRAD"&gt;&lt;span style="font-family:Calibri;font-size:small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=190630" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/omarvr/archive/tags/jquery/default.aspx">jquery</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/html/default.aspx">html</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/iphone/default.aspx">iphone</category></item><item><title>Sirviendo imágenes mediante ActionResult en MVC.</title><link>http://geeks.ms/blogs/omarvr/archive/2011/01/02/sirviendo-im-225-genes-mediante-actionresult-en-mvc.aspx</link><pubDate>Sun, 02 Jan 2011 14:21:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:186639</guid><dc:creator>Omar del Valle Rodríguez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/rsscomments.aspx?PostID=186639</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/commentapi.aspx?PostID=186639</wfw:comment><comments>http://geeks.ms/blogs/omarvr/archive/2011/01/02/sirviendo-im-225-genes-mediante-actionresult-en-mvc.aspx#comments</comments><description>&lt;p&gt;Hola, antes de empezar, desearles a todos un feliz inicio de a&amp;ntilde;o y que el trabajo que realicen le haga posible hacer realidad todas las metas que se han trazado. &lt;/p&gt;
&lt;p&gt;En el post de hoy vamos a ver c&amp;oacute;mo podemos servir im&amp;aacute;genes mediante un ActionResult en MVC. La pr&amp;aacute;ctica de este mecanismo puede ser aplicado a servir im&amp;aacute;genes desde una base de datos hacia nuestra WEB o, modificar una imagen que tengamos en el sistema de archivos antes de servirla a nuestra WEB. &lt;/p&gt;
&lt;p&gt;No hay truco alguno en esto, simplemente se trata de implementar un nuevo ActionResult que cargue la imagen desde donde queremos y luego la sirva al cliente como un arreglo de byte indicando que el contexto del resultado es del tipo Imagen. &lt;/p&gt;
&lt;p&gt;Vamos all&amp;aacute;&amp;hellip; &lt;/p&gt;
&lt;p&gt;Empezamos con el ejemplo m&amp;aacute;s simple. Saquemos la imagen de la base de datos y la servimos a la WEB.&lt;/p&gt;
&lt;div class="source-code"&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US" style="font-size:9.5pt;font-family:Consolas;color:blue;mso-ansi-language:EN-US;"&gt;public&lt;/span&gt;&lt;span lang="EN-US" style="font-size:9.5pt;font-family:Consolas;mso-ansi-language:EN-US;"&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;PhotoResult&lt;/span&gt; : ActionResult&lt;br /&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;override&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; ExecuteResult(ControllerContext context)&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; id = context.HttpContext.Request.QueryString[&lt;span style="color:#a31515;"&gt;&amp;quot;id&amp;quot;&lt;/span&gt;];&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US" style="font-size:9.5pt;font-family:Consolas;mso-ansi-language:EN-US;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;using&lt;/span&gt; (&lt;span style="color:blue;"&gt;var&lt;/span&gt; uow = &lt;span style="color:blue;"&gt;new&lt;/span&gt; UnitOfWork())&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; photoBytes = (&lt;span style="color:blue;"&gt;new&lt;/span&gt; CustomersDAC(uow).Load(id)).Photo.ToArray();&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US" style="font-size:9.5pt;font-family:Consolas;mso-ansi-language:EN-US;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;context.HttpContext.Response.ContentType = &lt;span style="color:#a31515;"&gt;&amp;quot;image/png&amp;quot;&lt;/span&gt;;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;context.HttpContext.Response.BinaryWrite(buffer);&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;context.HttpContext.Response.Flush();&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp; &lt;/span&gt;}&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Sencillo, implementamos una clase que herede de ActionResult y sobre-escribimos el m&amp;eacute;todo ExecuteResult. En este m&amp;eacute;todo tomamos un par&amp;aacute;metro &amp;ldquo;id&amp;rdquo; que nos enviar&amp;aacute;n por el QueryString y traemos de la base de datos una imagen que tenemos almacenada en forma de arreglo de bytes. &lt;/p&gt;
&lt;p&gt;Cuando tenemos el arreglo de bytes lo escribimos en la respuesta que se env&amp;iacute;a al cliente e indicamos que el tipo de contenido es imagen y su formato es png. &lt;/p&gt;
&lt;p&gt;Hasta aqu&amp;iacute; ya tenemos el ActionResult, ahora solo necesitamos un m&amp;eacute;todo en el controlador que nos retorne una instancia de PhotoResult.&lt;/p&gt;
&lt;div class="source-code"&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US" style="font-size:9.5pt;font-family:Consolas;color:blue;mso-ansi-language:EN-US;"&gt;public&lt;/span&gt;&lt;span lang="EN-US" style="font-size:9.5pt;font-family:Consolas;mso-ansi-language:EN-US;"&gt; &lt;span style="color:#2b91af;"&gt;PhotoResult&lt;/span&gt; GetPhotoByCustomer()&lt;br /&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;PhotoResult&lt;/span&gt;();&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Nada m&amp;aacute;s&amp;hellip; esto es todo lo que necesitamos para que el controlador ejecute nuestra acci&amp;oacute;n y retorne la imagen al cliente. &amp;iquest;C&amp;oacute;mo lo invocamos?&lt;/p&gt;
&lt;div class="source-code"&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US" style="font-size:9.5pt;font-family:Consolas;color:blue;mso-ansi-language:EN-US;"&gt;&amp;lt;&lt;/span&gt;&lt;span lang="EN-US" style="font-size:9.5pt;font-family:Consolas;color:maroon;mso-ansi-language:EN-US;"&gt;img&lt;/span&gt;&lt;span lang="EN-US" style="font-size:9.5pt;font-family:Consolas;mso-ansi-language:EN-US;"&gt; &lt;span style="color:red;"&gt;alt&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Your Photo&amp;quot;&lt;/span&gt; &lt;span style="color:red;"&gt;src&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;&lt;/span&gt;&lt;span style="background:yellow;mso-highlight:yellow;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;=&lt;/span&gt; Url.Action(&amp;quot;GetPhotoByCustomer?id=1&amp;quot;, &amp;quot;Home&amp;quot;) &lt;span style="background:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;quot;&lt;/span&gt; &lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Cuando el browser hace el GET al servidor para obtener el src de la imagen, en nuestra aplicaci&amp;oacute;n esto ser&amp;aacute; traducido a un Request al M&amp;eacute;todo que tenemos dentro del controlador, el cual se encargar&amp;aacute; de retornarnos la imagen solicitada. &lt;/p&gt;
&lt;p&gt;Otra aplicaci&amp;oacute;n que mencionamos al inicio del post y que puede tener esta manera de servir im&amp;aacute;genes al cliente es cuando queremos modificar una imagen que ya tenemos almacenada en el sistema de archivos antes de mostrarla. &lt;/p&gt;
&lt;p&gt;Imaginemos que tenemos una imagen a la cual queremos insertarle un copyright en el momento en que se sirva al cliente y de esta forma ahorrarnos tener que estar editando todas las im&amp;aacute;genes que vamos a utilizar antes de subir al servidor. &lt;/p&gt;
&lt;p&gt;El cambio para poder hacer lo anterior est&amp;aacute; solo en el ActionResult que implementamos. El resto de la implementaci&amp;oacute;n es exactamente igual. &lt;/p&gt;
&lt;div class="source-code"&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US" style="font-size:9.5pt;font-family:Consolas;color:blue;mso-ansi-language:EN-US;"&gt;public&lt;/span&gt;&lt;span lang="EN-US" style="font-size:9.5pt;font-family:Consolas;mso-ansi-language:EN-US;"&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;CopyrightImageResult&lt;/span&gt; : &lt;span style="color:#2b91af;"&gt;ActionResult&lt;br /&gt;&lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;const&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt; Copyright = &lt;span style="color:#a31515;"&gt;&amp;quot;Copyright (c) Omar del Valle Rodr&amp;iacute;guez&amp;quot;&lt;/span&gt;;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US" style="font-size:9.5pt;font-family:Consolas;mso-ansi-language:EN-US;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;override&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; ExecuteResult(&lt;span style="color:#2b91af;"&gt;ControllerContext&lt;/span&gt; context)&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; imagePath = context.HttpContext.Server.MapPath(&lt;span style="color:#a31515;"&gt;&amp;quot;/images/Photo.PNG&amp;quot;&lt;/span&gt;);&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; mainImage = &lt;span style="color:#2b91af;"&gt;Image&lt;/span&gt;.FromFile(imagePath);&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; memStream = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;MemoryStream&lt;/span&gt;();&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US" style="font-size:9.5pt;font-family:Consolas;mso-ansi-language:EN-US;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; fontCopyright = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Font&lt;/span&gt;(&lt;span style="color:#a31515;"&gt;&amp;quot;Arial&amp;quot;&lt;/span&gt;, 12);&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;const&lt;/span&gt; &lt;span style="color:blue;"&gt;float&lt;/span&gt; xCopyrightPoint = 493.0f;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;const&lt;/span&gt; &lt;span style="color:blue;"&gt;float&lt;/span&gt; yCopyrightPoint = 70.0f;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US" style="font-size:9.5pt;font-family:Consolas;mso-ansi-language:EN-US;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//create graphics from main image&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;using&lt;/span&gt; (&lt;span style="color:blue;"&gt;var&lt;/span&gt; g = &lt;span style="color:#2b91af;"&gt;Graphics&lt;/span&gt;.FromImage(mainImage))&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;g.DrawString(Copyright, fontCopyright, &lt;span style="color:#2b91af;"&gt;Brushes&lt;/span&gt;.Black, xCopyrightPoint, yCopyrightPoint);&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;mainImage.Save(memStream, &lt;span style="color:#2b91af;"&gt;ImageFormat&lt;/span&gt;.Png);&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US" style="font-size:9.5pt;font-family:Consolas;mso-ansi-language:EN-US;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; buffer = memStream.ToArray();&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US" style="font-size:9.5pt;font-family:Consolas;mso-ansi-language:EN-US;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;context.HttpContext.Response.ContentType = &lt;span style="color:#a31515;"&gt;&amp;quot;image/png&amp;quot;&lt;/span&gt;;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;context.HttpContext.Response.BinaryWrite(buffer);&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;context.HttpContext.Response.Flush();&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br /&gt;&lt;/span&gt;}&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Lo dicho, cargamos la imagen del sistema de archivos y dibujamos en ella lo que deseamos. Salvamos el resultado a un MemoryStream y lo retornamos como un arreglo de bytes al cliente. &lt;/p&gt;
&lt;p&gt;Salu2 y hasta la pr&amp;oacute;xima... &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=186639" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/omarvr/archive/tags/mvc/default.aspx">mvc</category></item><item><title>Llamada ajax en MVC usando el $.post de jquery</title><link>http://geeks.ms/blogs/omarvr/archive/2010/11/29/llamada-ajax-en-mvc-usando-el-post-de-jquery.aspx</link><pubDate>Mon, 29 Nov 2010 15:22:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:185385</guid><dc:creator>Omar del Valle Rodríguez</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/rsscomments.aspx?PostID=185385</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/commentapi.aspx?PostID=185385</wfw:comment><comments>http://geeks.ms/blogs/omarvr/archive/2010/11/29/llamada-ajax-en-mvc-usando-el-post-de-jquery.aspx#comments</comments><description>&lt;p&gt;Hace poco pas&amp;eacute; por la necesidad de enviar un formulario al servidor usando ajax en una aplicaci&amp;oacute;n MVC. El problema principal que ten&amp;iacute;a era que el formulario inclu&amp;iacute;a un n&amp;uacute;mero &amp;ldquo;grande&amp;rdquo; de campos (o no tan grande pero resulta que soy un vago), por lo que no quer&amp;iacute;a pasar el trabajo de tener que convertir todo eso a JSON como par&amp;aacute;metros individuales. Tampoco deseaba, evidentemente, tener un m&amp;eacute;todo en el controlador al cual le llegaran 5 o m&amp;aacute;s par&amp;aacute;metros. &lt;/p&gt;
&lt;p&gt;Pues bien&amp;hellip; la vista en mi caso estaba dise&amp;ntilde;ada para trabajar con un modelo definido por m&amp;iacute;: &lt;/p&gt;
&lt;div class="source-code"&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:blue;"&gt;public&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt; &lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;CustomerModel&lt;br /&gt;&lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt; UserName { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt; FirstName { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt; LastName { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt; Language { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&amp;nbsp;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;[&lt;span style="color:#2b91af;"&gt;DataType&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;DataType&lt;/span&gt;.Password)]&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt; Password { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;[&lt;span style="color:#2b91af;"&gt;DataType&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;DataType&lt;/span&gt;.Password)]&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt; ConfirmPassword { &lt;span style="color:blue;"&gt;get&lt;/span&gt;; &lt;span style="color:blue;"&gt;set&lt;/span&gt;; }&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;La vista: &lt;/p&gt;
&lt;div class="source-code"&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;background:yellow;mso-highlight:yellow;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:blue;"&gt;@&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt; &lt;span style="color:maroon;"&gt;Page&lt;/span&gt; &lt;span style="color:red;"&gt;Title&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;&amp;quot;&lt;/span&gt; &lt;span style="color:red;"&gt;Language&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;C#&amp;quot;&lt;/span&gt; &lt;span style="color:red;"&gt;MasterPageFile&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;~/Views/Shared/Site.Master&amp;quot;&lt;/span&gt; &lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:red;"&gt;Inherits&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:blue;"&gt;=&amp;quot;System.Web.Mvc.ViewPage&amp;lt;CustomerModel&amp;gt;&amp;quot;&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt; &lt;span style="background:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Mi formulario: &lt;/p&gt;
&lt;div class="source-code"&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;background:yellow;mso-highlight:yellow;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt; &lt;span style="color:blue;"&gt;using&lt;/span&gt; (Html.BeginForm()) { &lt;span style="background:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:blue;"&gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:maroon;"&gt;div&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;fieldset&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;legend&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;Customer Information&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;legend&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt; &lt;span style="color:red;"&gt;class&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;editor-label&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="background:yellow;mso-highlight:yellow;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt; Html.LabelFor(m =&amp;gt; m.FirstName) &lt;span style="background:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt; &lt;span style="color:red;"&gt;class&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;editor-field&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="background:yellow;mso-highlight:yellow;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt; Html.TextBoxFor(m =&amp;gt; m.FirstName) &lt;span style="background:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt; &lt;span style="color:red;"&gt;class&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;editor-label&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="background:yellow;mso-highlight:yellow;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt; Html.LabelFor(m =&amp;gt; m.LastName) &lt;span style="background:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt; &lt;span style="color:red;"&gt;class&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;editor-field&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="background:yellow;mso-highlight:yellow;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt; Html.TextBoxFor(m =&amp;gt; m.LastName) &lt;span style="background:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt; &lt;span style="color:red;"&gt;class&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;editor-label&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="background:yellow;mso-highlight:yellow;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt; Html.LabelFor(m =&amp;gt; m.UserName) &lt;span style="background:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt; &lt;span style="color:red;"&gt;class&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;editor-field&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="background:yellow;mso-highlight:yellow;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt; Html.TextBoxFor(m =&amp;gt; m.UserName) &lt;span style="background:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt; &lt;span style="color:red;"&gt;class&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;editor-label&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="background:yellow;mso-highlight:yellow;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt; Html.LabelFor(m =&amp;gt; m.Password) &lt;span style="background:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt; &lt;span style="color:red;"&gt;class&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;editor-field&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="background:yellow;mso-highlight:yellow;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt; Html.PasswordFor(m =&amp;gt; m.Password) &lt;span style="background:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt; &lt;span style="color:red;"&gt;class&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;editor-label&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="background:yellow;mso-highlight:yellow;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt; Html.LabelFor(m =&amp;gt; m.ConfirmPassword) &lt;span style="background:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt; &lt;span style="color:red;"&gt;class&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;editor-field&amp;quot;&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="background:yellow;mso-highlight:yellow;"&gt;&amp;lt;%&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt; Html.PasswordFor(m =&amp;gt; m.ConfirmPassword) &lt;span style="background:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;input&lt;/span&gt; &lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;button&amp;quot;&lt;/span&gt; &lt;span style="color:red;"&gt;onclick&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;uploadCustomerForm()&amp;quot;&lt;/span&gt; &lt;span style="color:red;"&gt;value&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;Register&amp;quot;&lt;/span&gt; &lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="ES-TRAD" style="font-size:9.5pt;font-family:Consolas;mso-ansi-language:ES-TRAD;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;p&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;fieldset&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;div&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="background:yellow;mso-highlight:yellow;"&gt;&amp;lt;%&lt;/span&gt; } &lt;span style="background:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;La soluci&amp;oacute;n ideal para m&amp;iacute; era poder pasar un objeto en javascript desde el cliente y que el controlador lo recibiera como el modelo asociado a la vista. Yo quer&amp;iacute;a que el m&amp;eacute;todo en mi controlador se viera as&amp;iacute;: &lt;/p&gt;
&lt;div class="source-code"&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;[&lt;span style="color:#2b91af;"&gt;AcceptVerbs&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;HttpVerbs&lt;/span&gt;.Post)]&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:blue;"&gt;&lt;br /&gt;public&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt; &lt;span style="color:#2b91af;"&gt;ActionResult&lt;/span&gt; SaveCustomer(&lt;span style="color:#2b91af;"&gt;CustomerModel&lt;/span&gt; model)&lt;br /&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt; Content(&lt;span style="color:blue;"&gt;string&lt;/span&gt;.Format(&lt;span style="color:#a31515;"&gt;&amp;quot;This is my content: {0}, {1}&amp;quot;&lt;/span&gt;, &lt;/span&gt;&lt;span lang="ES-TRAD" style="font-size:9.5pt;font-family:Consolas;mso-ansi-language:ES-TRAD;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;model.LastName, model.FirstName)); &lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Despu&amp;eacute;s de mucho andar por los rincones oscuros del mundo Google, hall&amp;eacute; una soluci&amp;oacute;n limpia, elegante y simple. &lt;/p&gt;
&lt;p&gt;Mi script: &lt;/p&gt;
&lt;div class="source-code"&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:maroon;"&gt;script&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt; &lt;span style="color:red;"&gt;src&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;/Scripts/jquery-1.4.1.min.js&amp;quot;&lt;/span&gt; &lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;script&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:blue;"&gt;&lt;br /&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:maroon;"&gt;script&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt; &lt;span style="color:red;"&gt;type&lt;/span&gt;&lt;span style="color:blue;"&gt;=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;function&lt;/span&gt; uploadCustomerForm()&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp; &lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; data = $(&lt;span style="color:maroon;"&gt;&amp;#39;form&amp;#39;&lt;/span&gt;).serialize();&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:darkgreen;"&gt;//Enviar por post&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;$.post(&lt;span style="color:maroon;"&gt;&amp;#39;&lt;span style="background:yellow;mso-highlight:yellow;"&gt;&amp;lt;%&lt;/span&gt; =Url.Action(&amp;quot;SaveCustomer&amp;quot;) &lt;span style="background:yellow;mso-highlight:yellow;"&gt;%&amp;gt;&lt;/span&gt;&amp;#39;&lt;/span&gt;, data, insertCallback);&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:blue;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;function&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt; insertCallback(data)&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp; &lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;alert(data);&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:maroon;"&gt;script&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Pues s&amp;iacute;, as&amp;iacute; de simple result&amp;oacute; pasar el formulario al controlador y que este recibiera como par&amp;aacute;metro el modelo asociado a la vista. Esta instrucci&amp;oacute;n resume todo lo que necesitamos: &lt;/p&gt;
&lt;div class="source-code"&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:blue;"&gt;var&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt; data = $(&lt;span style="color:maroon;"&gt;&amp;#39;form&amp;#39;&lt;/span&gt;).serialize();&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Pero, &amp;iquest;d&amp;oacute;nde est&amp;aacute; el truco? &lt;/p&gt;
&lt;p&gt;Cada elemento input de mi formulario se crea usando el helper Html.TextBoxFor el cual es asociado a una propiedad del modelo. Esto, si miramos el HTML generado, crea un input cuyo &lt;span style="text-decoration:line-through;"&gt;ID&lt;/span&gt; Name corresponde con el nombre de la propiedad que, al ser serializado, crea &lt;span style="text-decoration:line-through;"&gt;un JSON que hace corresponder ID=valor&lt;/span&gt; una representaci&amp;oacute;n en el formato cl&amp;aacute;sico de URL (param=valor&amp;amp;m2=valor2&amp;amp;...).&lt;/p&gt;
&lt;p&gt;Formulario serializado: &lt;/p&gt;
&lt;div class="source-code"&gt;FirstName=aa&amp;amp;LastName=bb&amp;amp;UserName=aa.bb&amp;amp;Password=123&amp;amp;ConfirmPassword=123 &lt;/div&gt;
&lt;p&gt;Una curiosidad a tener en cuenta es: si miran el formulario podr&amp;aacute;n ver que he dejado fuera del formulario la propiedad Language de mi modelo, esto lo he hecho con toda intensi&amp;oacute;n para que veamos que no es necesario que nuestro formulario se corresponda 100% con el modelo que tenemos asociado a la vista, pero, s&amp;iacute; es necesario que cada &lt;span style="text-decoration:line-through;"&gt;ID&lt;/span&gt; Name de los elementos del formulario se corresponda con una propiedad llamada exactamente igual a la existente en el modelo. &lt;/p&gt;
&lt;p&gt;Con esto&amp;hellip; ya tenemos un post por ajax al controlador que recibe como par&amp;aacute;metro el modelo asociado a la vista. Esto es posible tambi&amp;eacute;n hacerlo usando ASP.NET, pero eso lo dejo para un pr&amp;oacute;ximo art&amp;iacute;culo. &lt;/p&gt;
&lt;p&gt;;) &lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=185385" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/omarvr/archive/tags/ajax/default.aspx">ajax</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/jquery/default.aspx">jquery</category><category domain="http://geeks.ms/blogs/omarvr/archive/tags/mvc/default.aspx">mvc</category></item><item><title>Acceso al UI desde un hilo secundario en Silverlight</title><link>http://geeks.ms/blogs/omarvr/archive/2010/10/28/accesos-al-ui-desde-un-hilo-secundario-en-silverlight.aspx</link><pubDate>Thu, 28 Oct 2010 08:42:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:184035</guid><dc:creator>Omar del Valle Rodríguez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/rsscomments.aspx?PostID=184035</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/commentapi.aspx?PostID=184035</wfw:comment><comments>http://geeks.ms/blogs/omarvr/archive/2010/10/28/accesos-al-ui-desde-un-hilo-secundario-en-silverlight.aspx#comments</comments><description>&lt;p&gt;Todos los que hemos trabajado con aplicaciones Windows y en las cuales hemos necesitado interactuar con el UI desde un hilo secundario sabremos que esto requiere de un tratamiento especial. &lt;/p&gt;
&lt;p&gt;Hay una regla de oro cuando trabajamos WinForm e hilos: Con el UI solo se interact&amp;uacute;a desde el hilo principal de la aplicaci&amp;oacute;n. &lt;/p&gt;
&lt;p&gt;Ayer publiqu&amp;eacute; un art&amp;iacute;culo sobre un trabajo que vengo haciendo para conectar un servicio y un cliente Silverlight usando Socket. Los sockets usan comunicaci&amp;oacute;n asincr&amp;oacute;nica por lo que el evento de lectura de datos sobre el puerto ocurre en hilos secundarios que son creados por la conexi&amp;oacute;n para notificar a mi aplicaci&amp;oacute;n que tenemos informaci&amp;oacute;n nueva que tratar. &lt;/p&gt;
&lt;p&gt;C&amp;oacute;digo que inicializa y conecta el sockets en Silverlight: &lt;/p&gt;
&lt;div class="source-code"&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:#2b91af;"&gt;DnsEndPoint&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt; endPoint = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;DnsEndPoint&lt;/span&gt;(&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Application&lt;/span&gt;.Current.Host.Source.DnsSafeHost, 4530);&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:#2b91af;"&gt;&lt;br /&gt;Socket&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt; socket = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Socket&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;AddressFamily&lt;/span&gt;.InterNetwork, &lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;SocketType&lt;/span&gt;.Stream, &lt;span style="color:#2b91af;"&gt;ProtocolType&lt;/span&gt;.Tcp);&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:#2b91af;"&gt;SocketAsyncEventArgs&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt; args = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;SocketAsyncEventArgs&lt;/span&gt;();&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;br /&gt;args.UserToken = socket;&lt;br /&gt;args.RemoteEndPoint = endPoint;&lt;br /&gt;args.Completed += &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;EventHandler&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;SocketAsyncEventArgs&lt;/span&gt;&amp;gt;(OnSocketConnectCompleted);&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES-TRAD" style="font-size:9.5pt;font-family:Consolas;mso-ansi-language:ES-TRAD;"&gt;socket.ConnectAsync(args);&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Aqu&amp;iacute; podemos ver sin problemas la llamada al m&amp;eacute;todo ConnectAsync y la asignaci&amp;oacute;n del evento Completed que ser&amp;aacute; lanzado por el socket en el momento en que la conexi&amp;oacute;n o la lectura de datos sean completadas. &lt;/p&gt;
&lt;p&gt;La informaci&amp;oacute;n que me llega desde el servidor es transformada en objetos que son pintados din&amp;aacute;micamente en mi aplicaci&amp;oacute;n Silverlight. Esta operaci&amp;oacute;n es realizada en el m&amp;eacute;todo InitializeExtensionList: &lt;/p&gt;
&lt;div class="source-code"&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:blue;"&gt;private&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; OnSocketReceive(&lt;span style="color:blue;"&gt;object&lt;/span&gt; sender, &lt;span style="color:#2b91af;"&gt;SocketAsyncEventArgs&lt;/span&gt; e)&lt;br /&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; data = &lt;span style="color:#2b91af;"&gt;Encoding&lt;/span&gt;.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred);&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//Get initial team data&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt; (_extensions == &lt;span style="color:blue;"&gt;null&lt;/span&gt;)&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;InitializeExtensionList(data);&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//Prepare to receive more data&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Socket&lt;/span&gt; socket = (&lt;span style="color:#2b91af;"&gt;Socket&lt;/span&gt;)e.UserToken;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;socket.ReceiveAsync(e);&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Pues bien, al intentar ejecutar mi aplicaci&amp;oacute;n me encuentro con el siguiente mensaje:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://geeks.ms/cfs-filesystemfile.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/InvalidCrossThreadAccess.png" border="0" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Ummm&amp;hellip; Invalid Cross Thread Access: La excepci&amp;oacute;n es UnauthorizedAccessException. El mensaje de error habla por s&amp;iacute; solo. Se ha denegado el acceso al UI desde un hilo que no es el principal dentro de mi aplicaci&amp;oacute;n. &lt;/p&gt;
&lt;p&gt;En aplicaciones Windows esto se resolv&amp;iacute;a mediante un delegado que me permitiera sincronizar el acceso al UI con el hilo principal de la aplicaci&amp;oacute;n. &lt;/p&gt;
&lt;p&gt;Ejemplo en Windows Form: &lt;/p&gt;
&lt;div class="source-code"&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:#2b91af;"&gt;EventHandler&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt; m_progress = &lt;span style="color:blue;"&gt;delegate&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;br /&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_frmProgress.ShowQuality(userData.ToString());&lt;/span&gt;&lt;span lang="ES-TRAD" style="font-size:9.5pt;font-family:Consolas;mso-ansi-language:ES-TRAD;"&gt;&lt;br /&gt;};&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="ES-TRAD" style="font-size:9.5pt;font-family:Consolas;mso-ansi-language:ES-TRAD;"&gt;Invoke(m_progress);&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;El c&amp;oacute;digo dentro del delegado interact&amp;uacute;a con el UI, la sincronizaci&amp;oacute;n con el hilo principal se realiza mediante el m&amp;eacute;todo Invoque. &lt;/p&gt;
&lt;p&gt;Pero&amp;hellip; &amp;iquest;C&amp;oacute;mo Silverlight me permitir&amp;aacute; hacer esto? &lt;/p&gt;
&lt;p&gt;Pues por un lado tenemos la clase Dispatcher, la cual proporciona los servicios que me permiten manejar los elementos de trabajo de un subproceso. En otras palabras, ofrece compatibilidad para ejecutar c&amp;oacute;digo en el subproceso de interfaz de usuario de un subproceso que no es de interfaz de usuario. (Just in time! Esto me salva la vida.) &lt;/p&gt;
&lt;p&gt;Esta clase tiene un m&amp;eacute;todo llamado BeginInvoke el cual recibe como par&amp;aacute;metros un delegado y una matriz de valores que se pasan como argumentos (opcional). &lt;/p&gt;
&lt;p&gt;Pues nada, que la historia de sincronizaci&amp;oacute;n entre hilos secundarios y el hilo principal de la interfaz de usuario que tan com&amp;uacute;n es en Windows Form, sobre todo cuando trabajamos con SmartClient, se repite en Silverlight. ;) &lt;/p&gt;
&lt;p&gt;La forma correcta para ejecutar mi c&amp;oacute;digo ser&amp;iacute;a: &lt;/p&gt;
&lt;div class="source-code"&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:blue;"&gt;private&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; OnSocketReceive(&lt;span style="color:blue;"&gt;object&lt;/span&gt; sender, &lt;span style="color:#2b91af;"&gt;SocketAsyncEventArgs&lt;/span&gt; e)&lt;br /&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;var&lt;/span&gt; data = &lt;span style="color:#2b91af;"&gt;Encoding&lt;/span&gt;.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred);&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//Get initial team data&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt; (_extensions == &lt;span style="color:blue;"&gt;null&lt;/span&gt;)&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Dispatcher.BeginInvoke(() =&amp;gt; InitializeExtensionList(data));&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//Prepare to receive more data&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Socket&lt;/span&gt; socket = (&lt;span style="color:#2b91af;"&gt;Socket&lt;/span&gt;)e.UserToken;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;socket.ReceiveAsync(e);&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Seguimos ;)&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=184035" width="1" height="1"&gt;</description></item><item><title>Silverlight y los Sockets</title><link>http://geeks.ms/blogs/omarvr/archive/2010/10/27/silverlight-y-los-sockets-estableciendo-conexiones-con-el-servidor.aspx</link><pubDate>Wed, 27 Oct 2010 20:46:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:184005</guid><dc:creator>Omar del Valle Rodríguez</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/rsscomments.aspx?PostID=184005</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/commentapi.aspx?PostID=184005</wfw:comment><comments>http://geeks.ms/blogs/omarvr/archive/2010/10/27/silverlight-y-los-sockets-estableciendo-conexiones-con-el-servidor.aspx#comments</comments><description>&lt;p&gt;&amp;nbsp;Hace tiempo que vengo intentando cubrir algunos huecos en mi formaci&amp;oacute;n sobre .NET que por falta de tiempo se me hab&amp;iacute;a hecho imposible llevar adelante. Se trata de Silverlight y WPF. Ahora y por cuestiones de trabajo, me ha tocado hacer frente a estos &amp;ldquo;baches&amp;rdquo;. &lt;/p&gt;
&lt;p&gt;Como soy programador y no dise&amp;ntilde;ador, paso un poco de toda esta tecnolog&amp;iacute;a en la que las posibilidades de crear User Interface (UI) ricas en animaciones o efectos visuales cobra mayor importancia. As&amp;iacute;, enfrentar este nuevo reto me lleva por encontrar desde el punto de vista de an&amp;aacute;lisis y desarrollo, las posibilidades que estas nuevas tecnolog&amp;iacute;as traen asociadas. &lt;/p&gt;
&lt;p&gt;Uno de los principales problemas cuando desarrollamos en Web, es la posibilidad de una comunicaci&amp;oacute;n asincr&amp;oacute;nica entre cliente y servidor. Con esto me refiero a la posibilidad de que la comunicaci&amp;oacute;n fluya en ambos sentidos y no tenga que ser el cliente (Aplicaci&amp;oacute;n WEB) quien realice constantemente las peticiones al servidor. &lt;/p&gt;
&lt;p&gt;Silverlight es un Framework que corre del lado del cliente y que contiene una infraestructura que nos permite aumentar de modo significativo el alcance de nuestras aplicaciones Web. Partiendo de la problem&amp;aacute;tica anterior y conociendo las ventajas de esta nueva forma de desarrollo, me planteo para mi propio estudio la utilizaci&amp;oacute;n de sockets dentro de SilverLight para realizar una conexi&amp;oacute;n en la que el servidor sea quien se mantenga brindando continua informaci&amp;oacute;n al cliente. &lt;/p&gt;
&lt;p&gt;Esquema de desarrollo: &lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.odelvalle.com/images/silverlight_diagram.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;El esquema lo que muestra es una aplicaci&amp;oacute;n que desde un servidor interact&amp;uacute;a con una pizarra telef&amp;oacute;nica (PBX) mediante TAPI y env&amp;iacute;a hacia un cliente WEB desarrollado con Silverlight el estado actual de cada una de las extensiones conectadas a la PBX. Para el art&amp;iacute;culo, solo nos concentraremos en la comunicaci&amp;oacute;n por socket entre el cliente Web y el servidor. He dibujado el diagrama completo para que vean las l&amp;iacute;neas que representan el sentido en que fluye la informaci&amp;oacute;n en toda la aplicaci&amp;oacute;n. (Desde el servidor hacia el cliente) &lt;/p&gt;
&lt;p&gt;Empezamos desarrollando una aplicaci&amp;oacute;n de consola con un socket server como normalmente lo hemos visto siempre en cualquier aplicaci&amp;oacute;n Windows. Este socket server estar&amp;aacute; a la escucha mediante un determinado puerto de cualquier petici&amp;oacute;n de conexi&amp;oacute;n realizada desde un cliente Web. &lt;/p&gt;
&lt;p&gt;El TcpListener: Voy a pasar por alto la implementaci&amp;oacute;n detallada del servidor ya que no es el objetivo del art&amp;iacute;culo. &lt;/p&gt;
&lt;div class="source-code"&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:green;"&gt;//create our TCPListener object&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;br /&gt;_sockServer = &lt;span style="color:blue;"&gt;new&lt;/span&gt; System.Net.Sockets.&lt;span style="color:#2b91af;"&gt;TcpListener&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;IPAddress&lt;/span&gt;.Any, 4530);&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:#2b91af;"&gt;Console&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Started server...&amp;quot;&lt;/span&gt;);&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:blue;"&gt;try&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;br /&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//start the chat server&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_sockServer.Start();&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;while&lt;/span&gt; (&lt;span style="color:blue;"&gt;true&lt;/span&gt;)&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_tcpClientConnected.Reset();&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Waiting for client connection...&amp;quot;&lt;/span&gt;);&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&amp;nbsp;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_sockServer.BeginAcceptTcpClient(&lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;AsyncCallback&lt;/span&gt;(OnBeginAccept), &lt;span style="color:blue;"&gt;null&lt;/span&gt;);&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_tcpClientConnected.WaitOne(); &lt;span style="color:green;"&gt;//Block until client connects&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br /&gt;}&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:blue;"&gt;&lt;br /&gt;catch&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt; (&lt;span style="color:#2b91af;"&gt;Exception&lt;/span&gt; ex)&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;br /&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.Write(ex.ToString());&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&amp;hellip; OnBeginAccept &lt;/p&gt;
&lt;div class="source-code"&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:blue;"&gt;var&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt; _client = _sockServer.EndAcceptTcpClient(result);&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;br /&gt;InitializeExtensionList(_extensions);&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;_tcpClientConnected.Set(); &lt;span style="color:green;"&gt;//Allow waiting thread to proceed&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Con este c&amp;oacute;digo inicializamos nuestro servidor y lo mantenemos a la escucha sobre el puerto 4530 de cualquier petici&amp;oacute;n de conexi&amp;oacute;n. En el momento en que una conexi&amp;oacute;n es solicitada, se inicializa el listado de extensiones que no es m&amp;aacute;s que enviar al cliente la informaci&amp;oacute;n de todas las extensiones conectadas a la PBX. &lt;/p&gt;
&lt;p&gt;La primera observaci&amp;oacute;n es el puerto seleccionado. Esto no es un antojo, nuestro cliente ser&amp;aacute; una aplicaci&amp;oacute;n Silverlight y el mismo solo permite realizar conexiones por sockets a los puertos comprendidos en el rango de 4502 hasta el 4534. Cualquier intento de conexi&amp;oacute;n desde una aplicaci&amp;oacute;n desarrollada en Silverlight a un puerto fuera de este rango, ser&amp;aacute; denegado autom&amp;aacute;ticamente. &lt;/p&gt;
&lt;p&gt;Segunda observaci&amp;oacute;n es que usamos TCP como protocolo de comunicaci&amp;oacute;n, esto es lo normal cuando trabajamos con sockets aunque no est&amp;aacute; de m&amp;aacute;s indicar que es el &amp;uacute;nico protocolo permitido por Silverlight. &lt;/p&gt;
&lt;p&gt;Lanzamos nuestro server para asegurarnos que todo marcha bien&amp;hellip; &lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.odelvalle.com/images/silverlight_server.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Todo bien&amp;hellip; as&amp;iacute; que seguimos con lo que realmente importa, la aplicaci&amp;oacute;n cliente. &lt;/p&gt;
&lt;p&gt;MainPage.xaml.cs : No voy a entrar en detalles de dise&amp;ntilde;o o implementaci&amp;oacute;n del socket para no hacer extenso el art&amp;iacute;culo. &lt;/p&gt;
&lt;div class="source-code"&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:blue;"&gt;public&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt; MainPage()&lt;br /&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;InitializeComponent();&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;this&lt;/span&gt;.Loaded += Page_Loaded;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;En el constructor de mi UserControl me subscribo al evento Loaded en el cual conectar&amp;eacute; al servidor y esperar&amp;eacute; como respuesta el listado de extensiones.&lt;/p&gt;
&lt;div class="source-code"&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:blue;"&gt;void&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt; Page_Loaded(&lt;span style="color:blue;"&gt;object&lt;/span&gt; sender, &lt;span style="color:#2b91af;"&gt;RoutedEventArgs&lt;/span&gt; e)&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;br /&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;var&lt;/span&gt; endPoint = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;DnsEndPoint&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;Application&lt;/span&gt;.Current.Host.Source.DnsSafeHost, 4530);&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;var&lt;/span&gt; socket = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;Socket&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;AddressFamily&lt;/span&gt;.InterNetwork, &lt;span style="color:#2b91af;"&gt;SocketType&lt;/span&gt;.Stream, &lt;span style="color:#2b91af;"&gt;ProtocolType&lt;/span&gt;.Tcp);&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&amp;nbsp;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;SocketAsyncEventArgs&lt;/span&gt; args = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;SocketAsyncEventArgs&lt;/span&gt;();&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;args.UserToken = socket;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;args.RemoteEndPoint = endPoint;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;args.Completed += &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;EventHandler&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af;"&gt;SocketAsyncEventArgs&lt;/span&gt;&amp;gt;(OnSocketConnectCompleted);&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;socket.ConnectAsync(args);&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Aqu&amp;iacute; vamos&amp;hellip; Explicaci&amp;oacute;n rapidita: Este c&amp;oacute;digo identifica en primer lugar el servidor de la aplicaci&amp;oacute;n e inicializa un EndPoint mediante el puerto 4530 (Recuerden que Silverlight s&amp;oacute;lo puede conectarse a los servidores mediante los puerto 4502 al 4532). Posteriormente se crea un objeto Socket capaz de comunicarse mediante el protocolo TCP. Una vez que el objeto Socket es creado, creamos una instancia del objeto SocketAsyncEventArgs y asignamos el Socket a la propiedad UserToken de modo que podamos utilizarlo a trav&amp;eacute;s de otros m&amp;eacute;todos. El punto final de destino en el servidor se establece mediante la propiedad RemoteEndPoint y el evento Completed nos va a indicar el resultado de la conexi&amp;oacute;n. Una vez que estos objetos son creados y est&amp;aacute;n listos para su uso, El m&amp;eacute;todo ConnectAsync del objeto Socket puede ser llamado indicando como argumento el SocketAsyncEventArgs.&lt;/p&gt;
&lt;div class="source-code"&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:blue;"&gt;private&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; OnSocketConnectCompleted(&lt;span style="color:blue;"&gt;object&lt;/span&gt; sender, &lt;span style="color:#2b91af;"&gt;SocketAsyncEventArgs&lt;/span&gt; e)&lt;br /&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt; (e.SocketError == &lt;span style="color:#2b91af;"&gt;SocketError&lt;/span&gt;.Success)&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&amp;hellip; Success Connection&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;else&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Dispatcher.BeginInvoke(() =&amp;gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;System.Windows.Browser.&lt;span style="color:#2b91af;"&gt;HtmlPage&lt;/span&gt;.Window.Alert(e.SocketError.ToString()));&lt;/span&gt;&lt;span lang="ES-TRAD" style="font-size:9.5pt;font-family:Consolas;mso-ansi-language:ES-TRAD;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&amp;hellip;&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Con este c&amp;oacute;digo ya listo, lanzo mi aplicaci&amp;oacute;n cliente: &lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.odelvalle.com/images/silverlight_client.png" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;&amp;iexcl;&amp;iexcl;&amp;iexcl;BOOM!!! &amp;iquest;Acceso denegado? Y yo aprendiendo Silverlight, menudo problema. Mis primeros intentos de soluci&amp;oacute;n son los tan &amp;ldquo;mal&amp;rdquo; acostumbrados &amp;ldquo;prueba y error&amp;rdquo;. Sin tener muy claro qu&amp;eacute; estaba pasando empec&amp;eacute; a intentar adivinar. &lt;/p&gt;
&lt;p&gt;- Ya s&amp;eacute;&amp;hellip; el Firewall de Windows. Fuera Firewall pero el error segu&amp;iacute;a - Umm.. ya s&amp;eacute;&amp;hellip; el servidor no est&amp;aacute; funcionando bien. Hice una peque&amp;ntilde;a aplicaci&amp;oacute;n de consola que conectara al servidor y&amp;hellip; &amp;iexcl;&amp;iexcl;&amp;iexcl;funcion&amp;oacute; bien!!! &lt;/p&gt;
&lt;p&gt;Cansado de tanto estira y encoje hice lo que deb&amp;iacute;a hacer desde el principio. &amp;iexcl;Leer m&amp;aacute;s! &lt;/p&gt;
&lt;p&gt;Resulta que nuestro nuevo amiguito Silverlight establece unas pol&amp;iacute;ticas de seguridad, muy acertadas a mi criterio, en las que no permite conexi&amp;oacute;n alguna si antes el servidor no valida que realmente se tenga acceso a este recurso. &lt;/p&gt;
&lt;p&gt;El MSDN dice: &lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Silverlight 2 y las versiones posteriores son compatibles con la conectividad entre dominios, lo que permite a una aplicaci&amp;oacute;n obtener acceso a recursos situados en ubicaciones que no son el sitio de origen. Se trata de una caracter&amp;iacute;stica importante para que las aplicaciones de Silverlight puedan utilizar los servicios existentes en la Web. &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;El sistema de directivas de seguridad del motor en tiempo de ejecuci&amp;oacute;n de Silverlight requiere que se descargue un archivo de directivas desde un dominio de destino antes de permitir que una conexi&amp;oacute;n de red tenga acceso a un recurso de red que pertenezca a ese dominio de destino. Este sistema de directivas de seguridad afecta al acceso de red entre dominios para las clases WebClient y HTTP en el espacio de nombres System.Net.&amp;rdquo; &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;iquest;Qu&amp;eacute; archivo es este y qu&amp;eacute; contiene? &amp;iquest;D&amp;oacute;nde pongo este archivo? &lt;/p&gt;
&lt;p&gt;El archivo que expone las directivas de seguridad para que Silverlight pueda validar los recursos de red a los cuales deseamos acceder es un XML con el siguiente formato: &lt;/p&gt;
&lt;div class="source-code"&gt;
&lt;p class="MsoNormal"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;&amp;lt;access-policy&amp;gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&amp;lt;cross-domain-access&amp;gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&amp;lt;policy&amp;gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&amp;lt;allow-from&amp;gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&amp;lt;domain uri=&amp;quot;*&amp;quot; /&amp;gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&amp;lt;/allow-from&amp;gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&amp;lt;grant-to&amp;gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&amp;lt;socket-resource port=&amp;quot;4530&amp;quot; protocol=&amp;quot;tcp&amp;quot; /&amp;gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&amp;lt;/grant-to&amp;gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&amp;lt;/policy&amp;gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp; &lt;/span&gt;&amp;lt;/cross-domain-access&amp;gt;&lt;span lang="ES-TRAD" style="mso-ansi-language:ES-TRAD;"&gt;&lt;br /&gt;&amp;lt;/access-policy&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Relajitos con mi servidor &amp;iexcl;NO! ;) &lt;/p&gt;
&lt;p&gt;Mediante este archivo nosotros le indicamos a cualquier cliente que intente conectar a nuestro recurso de red, que solo tendr&amp;aacute; permiso si la petici&amp;oacute;n se realiza desde un dominio que est&amp;eacute; validado por nosotros (En este caso, v&amp;iacute;a libre a todo el mundo) y el recurso al que est&amp;eacute; intentando conectar sea s&amp;iacute; y solo s&amp;iacute;, el puerto 4530. Muy bien aqu&amp;iacute; por Microsoft ;) &lt;/p&gt;
&lt;p&gt;Ahora bien&amp;hellip; &amp;iquest;d&amp;oacute;nde pongo este archivo? De nuevo MSDN: &lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;En Silverlight versi&amp;oacute;n 3, en el caso de una solicitud de conexi&amp;oacute;n mediante System.Net.Sockets al sitio (entre dominios o sitio de origen), el runtime de Silverlight intenta abrir una conexi&amp;oacute;n utilizando TCP a un puerto conocido (el puerto 943) en el sitio de destino. Si se puede establecer una conexi&amp;oacute;n TCP, el runtime de Silverlight env&amp;iacute;a la cadena especial &lt;/em&gt;































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































&lt;em&gt;al servidor para solicitar un archivo de directivas de sockets de Silverlight. &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;El motor en tiempo de ejecuci&amp;oacute;n de Silverlight, a continuaci&amp;oacute;n, espera recibir una respuesta desde el sitio de destino que contenga un archivo de directivas de Silverlight. Si se devuelve este archivo de directivas de sockets de Silverlight (aun cuando haya un error de an&amp;aacute;lisis del archivo), se utiliza como archivo de directivas para esa solicitud de sockets y para todas las solicitudes subsiguientes a ese sitio de destino durante la sesi&amp;oacute;n completa de la aplicaci&amp;oacute;n de Silverlight.&amp;rdquo; &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Esto significa que para probar mis aplicaciones en Silverlight, de alg&amp;uacute;n modo necesito tener un servidor escuchando peticiones por el puerto 943 y, en caso de que se produzca una conexi&amp;oacute;n, validamos que se trate de un cliente solicitando un archivo de directiva de seguridad para retornarle el XML. &lt;/p&gt;
&lt;p&gt;Esto ser&amp;iacute;a un problema si pensamos hostear servicios en servidores que no sean dedicados, por eso, para el caso de Silverlight 4, la petici&amp;oacute;n de las directivas de seguridad se realizan tanto por el puerto 80, como por el puerto 943. De esta forma podemos adicionar a nuestro proyecto web el archivo XML para que los clientes accedan directamente a &amp;eacute;l. &lt;/p&gt;
&lt;p&gt;Para pruebas o cuando ejecutamos la aplicaci&amp;oacute;n dentro de Visual Studio, no podr&amp;iacute;amos publicar el XML por el puerto 80 ya que nuestra aplicaci&amp;oacute;n se ejecuta dentro del servidor web que trae el propio Visual Studio. &lt;/p&gt;
&lt;p&gt;Para poder probar mis aplicaciones sin problemas me cree un peque&amp;ntilde;o Socket server que valida y retorna el archivo de directivas de seguridad solicitado por Silverlight. &lt;/p&gt;
&lt;div class="source-code"&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;color:blue;"&gt;class&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt; &lt;span style="color:#2b91af;"&gt;PolicySocketServer&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;br /&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;TcpListener&lt;/span&gt; _listener = &lt;span style="color:blue;"&gt;null&lt;/span&gt;;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;TcpClient&lt;/span&gt; _client = &lt;span style="color:blue;"&gt;null&lt;/span&gt;;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;ManualResetEvent&lt;/span&gt; _tcpClientConnected = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;ManualResetEvent&lt;/span&gt;(&lt;span style="color:blue;"&gt;false&lt;/span&gt;);&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;const&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt; _policyRequestString = &lt;span style="color:#a31515;"&gt;&amp;quot;&amp;lt;policy-file-request/&amp;gt;&amp;quot;&lt;/span&gt;;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;int&lt;/span&gt; _receivedLength = 0;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;byte&lt;/span&gt;[] _policy = &lt;span style="color:blue;"&gt;null&lt;/span&gt;;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;byte&lt;/span&gt;[] _receiveBuffer = &lt;span style="color:blue;"&gt;null&lt;/span&gt;;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; ReadXmlPolicyData()&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;string&lt;/span&gt; policyFile = &lt;span style="color:#2b91af;"&gt;ConfigurationManager&lt;/span&gt;.AppSettings[&lt;span style="color:#a31515;"&gt;&amp;quot;PolicyFilePath&amp;quot;&lt;/span&gt;];&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;using&lt;/span&gt; (&lt;span style="color:#2b91af;"&gt;FileStream&lt;/span&gt; fs = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;FileStream&lt;/span&gt;(policyFile, &lt;span style="color:#2b91af;"&gt;FileMode&lt;/span&gt;.Open))&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;_policy = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:blue;"&gt;byte&lt;/span&gt;[fs.Length];&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;fs.Read(_policy, 0, _policy.Length);&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_receiveBuffer = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:blue;"&gt;byte&lt;/span&gt;[_policyRequestString.Length];&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; StartSocketServer()&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;ReadXmlPolicyData();&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_listener = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;TcpListener&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;IPAddress&lt;/span&gt;.Any, 943);&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_listener.Start();&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Policy server listening...&amp;quot;&lt;/span&gt;);&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;while&lt;/span&gt; (&lt;span style="color:blue;"&gt;true&lt;/span&gt;)&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_tcpClientConnected.Reset();&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="color:#a31515;"&gt;&amp;quot;Waiting for client connection...&amp;quot;&lt;/span&gt;);&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_listener.BeginAcceptTcpClient(&lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;AsyncCallback&lt;/span&gt;(OnBeginAccept), &lt;span style="color:blue;"&gt;null&lt;/span&gt;);&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_tcpClientConnected.WaitOne(); &lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; OnBeginAccept(&lt;span style="color:#2b91af;"&gt;IAsyncResult&lt;/span&gt; result)&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_client = _listener.EndAcceptTcpClient(result);&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_client.Client.BeginReceive(&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_receiveBuffer, 0, _policyRequestString.Length, &lt;span style="color:#2b91af;"&gt;SocketFlags&lt;/span&gt;.None,&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;AsyncCallback&lt;/span&gt;(OnReceiveComplete), &lt;span style="color:blue;"&gt;null&lt;/span&gt;);&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; OnReceiveComplete(&lt;span style="color:#2b91af;"&gt;IAsyncResult&lt;/span&gt; result)&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;try&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_receivedLength += _client.Client.EndReceive(result);&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt; (_receivedLength &amp;lt; _policyRequestString.Length)&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_client.Client.BeginReceive(&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_receiveBuffer, &lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_receivedLength, &lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_policyRequestString.Length - _receivedLength, &lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;SocketFlags&lt;/span&gt;.None, &lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;AsyncCallback&lt;/span&gt;(OnReceiveComplete), &lt;span style="color:blue;"&gt;null&lt;/span&gt;);&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt;;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//Check &amp;lt;policy-file-request/&amp;gt; &lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;string&lt;/span&gt; request = System.Text.&lt;span style="color:#2b91af;"&gt;Encoding&lt;/span&gt;.UTF8.GetString(&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_receiveBuffer, &lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;0, &lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_receivedLength);&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt; (&lt;span style="color:#2b91af;"&gt;StringComparer&lt;/span&gt;.InvariantCultureIgnoreCase.Compare(request, _policyRequestString) != 0)&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//Isn&amp;#39;t valid... bye bye&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_client.Client.Close();&lt;br /&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;return&lt;/span&gt;;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:green;"&gt;//Is Okay....send policy file&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_client.Client.BeginSend(&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_policy, &lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;0, &lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_policy.Length, &lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;SocketFlags&lt;/span&gt;.None, &lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;AsyncCallback&lt;/span&gt;(OnSendComplete), &lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;null&lt;/span&gt;);&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;catch&lt;/span&gt; (&lt;span style="color:#2b91af;"&gt;Exception&lt;/span&gt; ex)&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_client.Client.Close();&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.Write(ex.ToString());&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_receivedLength = 0;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_tcpClientConnected.Set(); &lt;span style="color:green;"&gt;//Allow waiting thread to proceed&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp; &lt;/span&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="font-size:9.5pt;font-family:Consolas;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;private&lt;/span&gt; &lt;span style="color:blue;"&gt;void&lt;/span&gt; OnSendComplete(&lt;span style="color:#2b91af;"&gt;IAsyncResult&lt;/span&gt; result)&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp; &lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;tr&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_client.Client.EndSendFile(result);&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;catch&lt;/span&gt; (&lt;span style="color:#2b91af;"&gt;Exception&lt;/span&gt; ex)&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:#2b91af;"&gt;Console&lt;/span&gt;.Write(ex.ToString());&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span style="color:blue;"&gt;finally&lt;/span&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;{&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;_client.Client.Close();&lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;} &lt;span style="mso-spacerun:yes;"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;}&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=184005" width="1" height="1"&gt;</description></item><item><title>Apuntes de un evento (POO) Parte 1</title><link>http://geeks.ms/blogs/omarvr/archive/2010/10/06/apuntes-de-un-evento-poo-parte-1.aspx</link><pubDate>Wed, 06 Oct 2010 11:27:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:182912</guid><dc:creator>Omar del Valle Rodríguez</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/rsscomments.aspx?PostID=182912</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/commentapi.aspx?PostID=182912</wfw:comment><comments>http://geeks.ms/blogs/omarvr/archive/2010/10/06/apuntes-de-un-evento-poo-parte-1.aspx#comments</comments><description>&lt;p&gt;Era mi primer evento online. Nunca hab&amp;iacute;a dado una clase o evento sin poder ver las caras de las personas que me escuchan. En principio pens&amp;eacute; que esto ser&amp;iacute;a malo, pero ya creo que tambi&amp;eacute;n tiene su parte buena.&lt;/p&gt;
&lt;p&gt;Lo malo, no podr&amp;eacute; saber si est&amp;aacute;n entendiendo o no lo que les estoy contando Lo bueno, no podr&amp;eacute; saber si tienen esa cara que se les queda a todo el mundo cuando se pregunta, &amp;ldquo;que tonter&amp;iacute;a est&amp;aacute; hablando este&amp;rdquo; ;)&lt;/p&gt;
&lt;p&gt;Ya parejos, F5:&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration:underline;"&gt;Encuesta&lt;/span&gt;: Con el objetivo de conocer la opini&amp;oacute;n&amp;nbsp;de los&amp;nbsp;presentes sobre programar o pensar orientado a objetos, se realiz&amp;oacute; la siguiente encuesta. &lt;/p&gt;
&lt;p&gt;1- &amp;iquest;Programamos orientado a objetos?&lt;br /&gt;2- Cuando programamos, &amp;iquest;Pensamos orientado a objetos?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Presentaci&amp;oacute;n&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;En este evento pretend&amp;iacute;amos repasar de forma muy elemental los principales conceptos sobre programaci&amp;oacute;n orientada a objetos. La mayor&amp;iacute;a de los lenguajes de programaci&amp;oacute;n son hoy en d&amp;iacute;a orientados a objetos. Esto puede traernos confusi&amp;oacute;n al pensar que por programar sobre un lenguaje que sea orientado a objetos, estamos programando orientado a objetos.&lt;/p&gt;
&lt;p&gt;Un posible ejemplo de esta confusi&amp;oacute;n es el desarrollo de aplicaciones ASPNET y el Desarrollo en Capas. Podemos crear un proyecto ASPNET donde todo el c&amp;oacute;digo est&amp;eacute; en un mismo proyecto, donde las consultas se realicen escribiendo directamente el SQL en el code behind y nuestro programa funcionar&amp;iacute;a, pero &amp;iquest;Es correcto? NO&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Un poco de historia &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;iquest;C&amp;oacute;mo surge todo esto de la programaci&amp;oacute;n orientada a objetos y d&amp;oacute;nde radica su verdadera importancia?&lt;/p&gt;
&lt;p&gt;Todo empez&amp;oacute; en la llamada &amp;ldquo;crisis del software&amp;rdquo; entre los a&amp;ntilde;os 60 y 70. &lt;/p&gt;
&lt;p&gt;&amp;iquest;En qu&amp;eacute; consist&amp;iacute;a esta crisis?&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/Diapositiva2.PNG"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/Diapositiva2.PNG" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Los &amp;quot;grandes&amp;quot; grupos de programadores que programaban los &amp;quot;grandes&amp;quot; sistemas para los &amp;quot;grandes&amp;rdquo; ordenadores ten&amp;iacute;an serios problemas de organizaci&amp;oacute;n y productividad. Pocos sistemas lograban terminarse, en pocos se terminaban cumpliendo los requerimientos iniciales y no todos los que se terminaban cumpli&amp;eacute;ndolos, se usaban seg&amp;uacute;n lo planificado. &lt;/p&gt;
&lt;p&gt;El problema, que en aquel entonces se llam&amp;oacute; de forma incorrecta de &amp;ldquo;mantenimiento&amp;rdquo;, consist&amp;iacute;a en c&amp;oacute;mo adaptar el software a nuevos requerimientos imposibles de haber sido planificados inicialmente.&lt;/p&gt;
&lt;p class="style1"&gt;&lt;span style="text-decoration:underline;"&gt;La planificaci&amp;oacute;n y previsi&amp;oacute;n es contrario a la propia realidad.&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;Nosotros, las personas, aprendemos y creamos a trav&amp;eacute;s de la experimentaci&amp;oacute;n, no de la planificaci&amp;oacute;n. Si no hay experiencia, no aprendemos, y la experiencia solo llega experimentando y no planificando.&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration:underline;"&gt;Soy un ni&amp;ntilde;o y quiero correr (Experimentar) me ca&amp;iacute; y me di un golpe (Experiencia) ya s&amp;eacute; que no puedo correr sino que debo caminar (ense&amp;ntilde;anza) &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration:underline;"&gt;Es imposible y eso creo que todos los sabemos, que exista un proyecto que pueda ser planificado por entero antes de escribir una l&amp;iacute;nea de c&amp;oacute;digo, y mucho m&amp;aacute;s imposible, convertir la planificaci&amp;oacute;n en una camisa de fuerza en el desarrollo y evoluci&amp;oacute;n del sistema.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;A&amp;uacute;n en la actualidad, se lucha por crear planificaciones adaptables. Las Metodolog&amp;iacute;as &amp;aacute;giles, por ejemplo, intentan planificar un proyecto de software adapt&amp;aacute;ndolo constantemente a los cambios que surgen durante su etapa de desarrollo.&lt;/p&gt;
&lt;p&gt;&amp;iquest;Por qu&amp;eacute; toda esta historia? &lt;/p&gt;
&lt;p&gt;&amp;iquest;Es la POO un mejor paradigma que otros? En cierto sentido s&amp;iacute; lo es. &amp;iquest;Es una cura de todos nuestros problemas? No, no lo es. &amp;iquest;Significa que &amp;quot;crisis del software&amp;quot; desaparecer&amp;aacute;? Probablemente no. Y entonces se preguntar&amp;aacute;n, &amp;iquest;qu&amp;eacute; es lo grande de la Programaci&amp;oacute;n Orientada a Objetos?&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration:underline;"&gt;&lt;span class="style1"&gt;Acercar el ordenador al problema y no al rev&amp;eacute;s. &lt;/span&gt;En lugar de tratar de modelar un problema en algo familiar al ordenador, se trata ahora de acercar el ordenador al problema. Se trata en todo momento de modelar los problemas existentes en la vida real&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Principales pilares de la programaci&amp;oacute;n orientada a objetos.&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/Diapositiva3.PNG"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/omarvr/Diapositiva3.PNG" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Encapsulamiento:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Es importante limitar correctamente el acceso a un objeto. Un objeto es un elemento que contiene propiedades y que realiza acciones. &lt;/p&gt;
&lt;p&gt;Un avi&amp;oacute;n tiene ruedas, un color, puertas, &lt;span style="text-decoration:line-through;"&gt;halas&lt;/span&gt; alas.&amp;nbsp;Adem&amp;aacute;s realiza acciones como despegar, aterrizar, planear, girar a un sentido u otro. Sobre el avi&amp;oacute;n se realizan acciones que cambian su comportamiento y este, modifica el estado.&lt;/p&gt;
&lt;p&gt;Supongamos que el avi&amp;oacute;n contiene un estado que nos indica si est&amp;aacute; en tierra o en el aire. Jam&amp;aacute;s deber&amp;iacute;amos poder modificar ese estado si no es mediante una acci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;- Estado (En tierra)&lt;br /&gt;- Acci&amp;oacute;n (Despegar). Si despegar fue correcto, cambiar estado (en el aire)&lt;br /&gt;- Estado (En el aire)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Herencia:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Hay que procrear, procreen mucho y as&amp;iacute; damos continuidad a nuestra especie. Pero, cuidado, no se puede ir haciendo hijos por ah&amp;iacute; si no estamos seguros de que le vamos a transmitir y que van a usar todo lo que sabemos.&lt;/p&gt;
&lt;p&gt;Esto es herencia. Necesitamos hijos que se apoyen de nuestra experiencia y la apliquen en forma de ense&amp;ntilde;anza. Lo s&amp;eacute;, porque mi padre me lo dijo y listo. C&amp;oacute;mo lo supo el padre no importa, eso queda en el encapsulamiento ;) &lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration:underline;"&gt;Piensen en el ejemplo del ni&amp;ntilde;o que corre. Los padres constantemente intentan transmitir cuidado, ense&amp;ntilde;anzas de que no se debe correr para evitar un golpe. El ni&amp;ntilde;o no se preocupa c&amp;oacute;mo sus padres lo aprendieron, &amp;ldquo;casi siempre&amp;rdquo; obedecen.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Pero, de nuevo tenemos que tener mucho cuidado. Si un hijo, a pesar de conocer la experiencia del padre termina por no usarla y crear una personalidad propia, entonces ya no existe herencia, sino que ser&amp;iacute;an dos personas totalmente distintas. Dos objetos distintos.&lt;/p&gt;
&lt;p&gt;La herencia, entre otras cosas, es para un inform&amp;aacute;tico el pan nuestro de cada d&amp;iacute;a. Reutilizaci&amp;oacute;n, no escriban lo mismo dos veces.&lt;span style="text-decoration:underline;"&gt; El tiempo es dinero y hasta un minuto puede costar caro. Piensen, piensen y piensen. Si hay dos objetos que tienen similar comportamiento, el mantenimiento de los mismos de manera separada multiplica por dos el tiempo para realizarlo.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cohesi&amp;oacute;n/ Especializaci&amp;oacute;n (ver comentarios al final del art&amp;iacute;culo):&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Esto es la especializaci&amp;oacute;n de cada objeto. Tenemos que llegar a lograr que cada objeto se especialice solo en lo que sabe hacer, extendernos har&amp;iacute;a que termin&amp;aacute;ramos mezclando funcionalidad.&lt;/p&gt;
&lt;p&gt;La silla, fue dise&amp;ntilde;ada solo para sentarnos. Algunos la usamos como escalera, pero no fue dise&amp;ntilde;ado para eso. Cuando usamos la silla como escalera y nos caemos decimos: claro, era una silla y no una escalera.&lt;/p&gt;
&lt;p&gt;El perro es un perro y el gato es un gato, no hay un perro-gato. Un coche es un coche y un avi&amp;oacute;n es un avi&amp;oacute;n. Y si no me creen, intenten volar con un coche.&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration:underline;"&gt;Los objetos mientras mayor sea su cohesi&amp;oacute;n, mejor podremos definir su comportamiento.&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Abstracci&amp;oacute;n:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration:underline;"&gt;Aqu&amp;iacute; pensamos en qu&amp;eacute; hace y no en c&amp;oacute;mo lo hace&lt;/span&gt;. Dentro de la programaci&amp;oacute;n orientada a objeto la Abstracci&amp;oacute;n nos permite definir caracter&amp;iacute;sticas del objeto, modelar su comportamiento sin llegar a especificar el c&amp;oacute;mo lo hace.&lt;/p&gt;
&lt;p&gt;En la realidad, el ser humano no piensa en las cosas como un conjunto de peque&amp;ntilde;as cosas sino que las entendemos como objetos con comportamientos bien definidos.&lt;/p&gt;
&lt;p&gt;Una persona es un objeto con un comportamiento bien definido. Cuando una persona desea desplazarse, el cuerpo responde caminando. En ese momento no pensamos c&amp;oacute;mo nuestro deseo lleg&amp;oacute; al cerebro y este env&amp;iacute;a el mensaje en forma de acci&amp;oacute;n hacia los m&amp;uacute;sculos de los pies para provocar el movimiento. Simplemente, caminamos y eso define el comportamiento.&lt;/p&gt;
&lt;p&gt;El principio de abstracci&amp;oacute;n es precisamente esto: Lograr tener objetos con comportamientos bien definidos e irlos dividiendo sucesivamente en conjuntos de subsistemas cada vez m&amp;aacute;s especializados.&lt;/p&gt;
&lt;p&gt;El objeto animal es un ejemplo de abstracci&amp;oacute;n, tiene caracter&amp;iacute;sticas como edad, sexo, color y realiza acciones como comer, dormir o desplazarse. La especializaci&amp;oacute;n de esta abstracci&amp;oacute;n podr&amp;iacute;a ser un objeto perro, gato, paloma o persona, cada nuevo objeto implementa el c&amp;oacute;mo har&amp;aacute; cada acci&amp;oacute;n. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Polimorfismo:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Es la capacidad que permite mantener organizada varias acciones en objetos heredados que aun significando lo mismo, se realizan de manera diferente.&lt;/p&gt;
&lt;p&gt;Existen aviones de combate que pueden despegar desde un porta-aviones en el medio del mar, otros que no tienen tal capacidad y lo hacen siempre desde una pista. La acci&amp;oacute;n a realizar es Despegar, pero la manera en que lo hacen es diferente. &lt;/p&gt;
&lt;p&gt;En POO, el polimorfismo se aplica cuando necesitamos sobre escribir m&amp;eacute;todos o atributos llamados de forma id&amp;eacute;ntica pero con un comportamiento distinto. &lt;/p&gt;
&lt;p&gt;&lt;span class="style1"&gt;&lt;span style="text-decoration:underline;"&gt;No confundir polimorfismo con sobre-carga&lt;/span&gt;&lt;/span&gt;: Polimorfismo (Entre clases, se resuelve en tiempo de ejecuci&amp;oacute;n) Sobre-carga (m&amp;eacute;todos de la misma clase, se resuelve en tiempo de compilaci&amp;oacute;n)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Acoplamiento:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Es la dependencia existente entre objetos para poder funcionar. &lt;/p&gt;
&lt;p&gt;La comunicaci&amp;oacute;n entre objetos siempre se realiza mediante acciones (llamadas a m&amp;eacute;todos) y es conocida como comunicaci&amp;oacute;n por mensajes. Haz esto, hora t&amp;uacute; haz aquello para yo luego poder hacer lo m&amp;iacute;o.&lt;/p&gt;
&lt;p&gt;Si bien es verdad que mientras menos acoplamiento exista entre los objetos, mejor encapsulado quedar&amp;aacute; el objeto, debemos tener mucho cuidado en no mezclar responsabilidades. &lt;/p&gt;
&lt;p&gt;Una tuerca es un objeto con una funcionalidad bien definida: Apretar o asegurar algo. A nadie hasta ahora se le ha ocurrido crear una tuerca que se ajuste por s&amp;iacute; misma. A la tuerca, se le hace rosca, que es quien permite el ajuste y por fuera se le da diferentes formas seg&amp;uacute;n la herramienta que se desee utilizar posteriormente para ajustar dicha tuerca. Unir la funcionalidad de ambos objetos (tuerca y llave) en uno solo implica que estemos mezclando responsabilidades. &lt;/p&gt;
&lt;p&gt;Una manera de darnos cuenta de estas cosas es cuando nuestras clases crecen y crecen y crecen. Si esto pasa, paremos por un instante a pensar si no estamos mezclando funcionalidad de varios objetos en uno solo.&lt;/p&gt;
&lt;p&gt;PD: Este art&amp;iacute;culo continuar&amp;aacute; con la explicaci&amp;oacute;n de los ejemplos utilizados en el evento. De todas formas, pueden descargarse toda la documentaci&amp;oacute;n y ver el evento desde la p&amp;aacute;gina del grupo de usuarios&amp;nbsp;&lt;a target="_blank" href="http://www.secondnug.com"&gt;SNUG&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Salu2&lt;/p&gt;
&lt;p&gt;Bibliograf&amp;iacute;a utilizada: Programaci&amp;oacute;n Orientada a Objetos en C++ - Miguel Katrib Mora.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=182912" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/omarvr/archive/tags/POO/default.aspx">POO</category></item><item><title>CommonApplicationData y sus permisos</title><link>http://geeks.ms/blogs/omarvr/archive/2010/03/29/commonapplicationdata-y-sus-permisos.aspx</link><pubDate>Mon, 29 Mar 2010 13:41:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:171603</guid><dc:creator>Omar del Valle Rodríguez</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/rsscomments.aspx?PostID=171603</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/omarvr/commentapi.aspx?PostID=171603</wfw:comment><comments>http://geeks.ms/blogs/omarvr/archive/2010/03/29/commonapplicationdata-y-sus-permisos.aspx#comments</comments><description>&lt;p&gt;Aqu&amp;iacute; les dejo un tips de WinForm tan r&amp;aacute;pido como me lo permite el tiempo.&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration:underline;"&gt;&lt;strong&gt;Problem&amp;aacute;tica&lt;/strong&gt;&lt;/span&gt;:&amp;nbsp;Necesitamos&amp;nbsp;crear&amp;nbsp;archivos desde nuestra aplicaci&amp;oacute;n que&amp;nbsp;sean modificados por todos los usuarios del sistema operativo sin importar los permisos otorgados. Microsoft aconseja que cuando necesitemos guardar este tipo de informaci&amp;oacute;n, usemos el CommonApplicationData, el cual es accesible para todos los usuarios.&lt;/p&gt;
&lt;div class="source-code"&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US" style="LINE-HEIGHT:115%;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;COLOR:#2b91af;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;Environment&lt;/span&gt;&lt;span lang="EN-US" style="LINE-HEIGHT:115%;FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;.GetFolderPath(&lt;span style="COLOR:#2b91af;"&gt;Environment&lt;/span&gt;.&lt;span style="COLOR:#2b91af;"&gt;SpecialFolder&lt;/span&gt;.CommonApplicationData)&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;La estructura organizativa que se aconseja mantener en dicho directorio ser&amp;iacute;a [&lt;em&gt;&lt;span style="text-decoration:underline;"&gt;Nombre de la compa&amp;ntilde;&amp;iacute;a\Nombre de la aplicaci&amp;oacute;n&lt;/span&gt;&lt;/em&gt;], pero esto incluye una problem&amp;aacute;tica a nuestro desarrollo, y es que a los archivos creados desde nuestra aplicaci&amp;oacute;n, se les asignan permisos de escritura restringidos solo a su creador (El usuario que ejecuta la aplicaci&amp;oacute;n) y a cuentas administrativas (Administrador local y administradores de dominio). Si posteriormente nos autentificamos en el sistema operativo con otro usuario cuyos derechos est&amp;aacute;n limitados solamente al grupo [&lt;em&gt;&lt;span style="text-decoration:underline;"&gt;Todos los usuarios&lt;/span&gt;&lt;/em&gt;], se nos denegar&amp;aacute; el acceso a modificar los archivos creados por el usuario anterior.&lt;/p&gt;
&lt;p&gt;&lt;span style="text-decoration:underline;"&gt;&lt;strong&gt;Resoluci&amp;oacute;n&lt;/strong&gt;&lt;/span&gt;: Al crear la carpeta que contendr&amp;aacute; nuestros archivos para la aplicaci&amp;oacute;n, asign&amp;eacute;mosle permisos especiales que le permitan a todos los usuarios tener acceso total a la misma, posteriormente indicamos que dichos accesos son heredables por todos los objetos que se encuentren dentro y... problema resuelto.&lt;/p&gt;
&lt;p&gt;Aqu&amp;iacute; les dejo una peque&amp;ntilde;a clase que permite crear carpetas desde nuestra aplicaci&amp;oacute;n indicando si deseamos asignar acceso total a todos los usuarios.&lt;/p&gt;
&lt;div class="source-code"&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US" style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="COLOR:blue;"&gt;public&lt;/span&gt; &lt;span style="COLOR:blue;"&gt;class&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;CommonApplicationData&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span lang="EN-US" style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&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; CreateFolder(&lt;span style="COLOR:blue;"&gt;string&lt;/span&gt; folderName, &lt;span style="COLOR:blue;"&gt;bool&lt;/span&gt; allUsers)&lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;if&lt;/span&gt; (&lt;span style="COLOR:#2b91af;"&gt;Directory&lt;/span&gt;.Exists(folderName)) &lt;span style="COLOR:blue;"&gt;return&lt;/span&gt;;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US" style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US" style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;var&lt;/span&gt; m_securityIdentifier =&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;SecurityIdentifier&lt;/span&gt;(&lt;span style="COLOR:#2b91af;"&gt;WellKnownSidType&lt;/span&gt;.WorldSid, &lt;span style="COLOR:blue;"&gt;null&lt;/span&gt;);&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US" style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US" style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;var&lt;/span&gt; m_directoryInfo = &lt;span style="COLOR:#2b91af;"&gt;Directory&lt;/span&gt;.CreateDirectory(folderName);&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US" style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;if&lt;/span&gt; (!allUsers) &lt;span style="COLOR:blue;"&gt;return&lt;/span&gt;;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US" style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US" style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;bool&lt;/span&gt; m_modified;&lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR:blue;"&gt;var&lt;/span&gt; m_directorySecurity = m_directoryInfo.GetAccessControl(); &lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US" style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR:#2b91af;"&gt;AccessRule&lt;/span&gt; m_rule = &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span lang="EN-US" style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="COLOR:blue;"&gt;new&lt;/span&gt; &lt;span style="COLOR:#2b91af;"&gt;FileSystemAccessRule&lt;/span&gt;(m_securityIdentifier, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span lang="EN-US" style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="COLOR:#2b91af;"&gt;FileSystemRights&lt;/span&gt;.FullControl,&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="COLOR:#2b91af;"&gt;InheritanceFlags&lt;/span&gt;.ContainerInherit |&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR:#2b91af;"&gt;InheritanceFlags&lt;/span&gt;.ObjectInherit,&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="COLOR:#2b91af;"&gt;PropagationFlags&lt;/span&gt;.InheritOnly,&amp;nbsp;&lt;br /&gt;&lt;/span&gt;&lt;span lang="EN-US" style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="COLOR:#2b91af;"&gt;AccessControlType&lt;/span&gt;.Allow);&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US" style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US" style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;m_directorySecurity.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;span lang="EN-US" style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;ModifyAccessRule(&lt;span style="COLOR:#2b91af;"&gt;AccessControlModification&lt;/span&gt;.Add,&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span lang="EN-US" style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;m_rule, &lt;span style="COLOR:blue;"&gt;out&lt;/span&gt; m_modified);&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span lang="EN-US" style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-ansi-language:EN-US;mso-no-proof:yes;"&gt;&lt;span style="mso-spacerun:yes;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-no-proof:yes;"&gt;m_directoryInfo.SetAccessControl(m_directorySecurity);&lt;br /&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-no-proof:yes;"&gt;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="FONT-FAMILY:&amp;#39;Courier New&amp;#39;;FONT-SIZE:8pt;mso-no-proof:yes;"&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Salu2&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=171603" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/omarvr/archive/tags/winform+permisos+c_2300_/default.aspx">winform permisos c#</category></item></channel></rss>
