Después de la última sacudida recibida
por la encapsulación del Container que hicimos en el artículo anterior, sacamos este Service Pack 1
y de paso cuento un poco cómo llegamos aquí.
Cuando me pasan estas cosas, siempre recuerdo el pasaje de una lectura que tengo por casa…
“Denis Cochin preparo un estudio sobre Química y lo presento a Pasteur. El trabajo comenzaba con las palabras. “Se sabe que...“
- ¿Que es lo que se sabe? - Interrumpió Pasteur al leerlo. - No se sabe nada.
- Pero señor - Contesto Cochin - lo que iba a citar es un trabajo de usted.
- No importa - replico Pasteur. - Yo podría haberme equivocado. Empiece Ud. de nuevo”
Tras los comentarios de Unai y Eduard más la referencia al artículo de Mark sobre el patrón o anti-patrón Service-Locator (Martin Fowler, 2004), había que profundizar más en el tema, así que sin pensarlo dos veces me compré el libro de “Dependency Injection in .NET” el cual recomiendo muchísimo por la claridad en el contenido, además de estar orientado directamente a NET.
En el libro, cuando Mark habla del Service Locator como un anti-patrón, dice: “Some people consider it a proper design pattern, whereas others (me included) consider it an anti-pattern.”
Tras esta definición no puedo evitar preguntarme ¿Y en qué bando me pongo yo? Es evidente que la opinión de Eduard, Unai, Mark y seguramente la de muchos otros, pesa muchísimo, así que lo más probable es que termine más rápido si busco alguna deficiencia en la implementación anterior que me lleve finalmente a verlo como ellos.
Tras no mucho tiempo… me imaginé la siguiente situación:
Tengo varios controladores (MVC) que usan inyección de dependencia con uno o varios servicios (Application services), tengo servicios que usan dependencias a uno o má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ón. En esa situación, tendré 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é también llamadas al Resolve en los repositorios para recuperar la unidad de trabajo y así en toda mi arquitectura...
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. ¿Qué pasa si quiero reutilizar los repositorios? ¿O si quiero reutilizar los servicios? ¿O si quiero reutilizar mi unidad de trabajo? Pues que en todo momento dependeré del Service Locator…
No seguí buscando… mi objetivo era estar desacoplado del Framework de IoC y terminé atando toda la arquitectura.
¿Cómo soluciono esto entonces?
-Constructor Inyection
-Property Injection
-…
Si mis controladores recibieran los servicios que necesitan para trabajar mediante el constructor, no necesitaría una referencia al Service Locator… y lo mismo pasa en toda la cadena de inyección.
¿Cómo funciona esto? Imaginen que tengo…
Controller(IService srv) – Service(IRepository repo) – Repository(IUnitofWork uow) – UnitOfWork()
1- Un controlador necesita una instancia de un servicio, se intenta crear una instancia de ese servicio.
2- Para crear el servicio se necesita un repositorio, se intenta crear una instancia del repositorio.
3- Para crear el repositorio se necesita una unidad de trabajo, se intenta crear la unidad de trabajo.
4- Se crea la unidad de trabajo (no depende de nadie).
5- A partir de aquí, se inyecta la unidad de trabajo al repositorio, el repositorio al servicio y el servicio al controlador.
Este algoritmo me dice que todo empieza desde un punto único. A este punto Mark lo llama Composition Root. “A COMPOSITION ROOT is a (preferably) unique location in an application where modules are composed together.”
Un DI Container es quien me dice quién es el Container utilizado en mi aplicación y el encargado de componer todo el grafo de objetos. Este debe ser referenciado únicamente desde el Composition root (De aquí 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ón.
Conociendo un poco más que ayer, decidí hacer “refactoring” 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és de un rato, me quedó esto:
Mi DI Container. …
public static class UnityContainerFactory
{
private static readonly IUnityContainer _container;
static UnityContainerFactory()
{
_container = new UnityContainer();
Configure();
}
private static void Configure()
{
var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Configure(_container);
// Aditional Configuration
// Container.RegisterType<IBaseType, ModuleAType>("moduleA")
// Container.RegisterType<IBaseType, ModuleBType>("moduleB")
}
public static IUnityContainer GetContainer()
{
return _container;
}
}
¿Quién sería mi Composition Root? Pues ya esto depende del tipo de aplicación que se vaya a crear, ya que cada aplicación puede tener una definición diferente para su “único punto de entrada”. Por ejemplo, para una aplicación MVC, Mark aconseja un IControllerFactory, aunque si es para MVC3, yo prefiero el IDependencyResolver.
Mi Composition Root para MVC3 sería:
public class UnityDependencyResolver : IDependencyResolver
{
private readonly IUnityContainer _container;
#region Implementation of IDependencyResolver
public UnityDependencyResolver(IUnityContainer container)
{
_container = container;
}
public object GetService(Type serviceType)
{
return _container.IsRegistered(serviceType) ? _container.Resolve(serviceType) : null;
}
public IEnumerable<object> GetServices(Type serviceType)
{
return _container.ResolveAll<object>().Where(s => s.GetType() == serviceType);
}
}
Aquí puedes encontrar un pequeño post de Steve explicando la implementación anterior.
Para el caso de un servicio WCF me gustó la forma en que lo implementaron en la guía de arquitectura N Layer donde se implementa la interfaz IInstanceProvider:
public class UnityDependencyProvider : IInstanceProvider
{
private readonly IUnityContainer _container;
private readonly Type _serviceType;
public UnityDependencyProvider(Type serviceType)
{
if (serviceType == null) throw new ArgumentNullException("serviceType");
_serviceType = serviceType;
_container = UnityContainerFactory.GetContainer();
}
#region Implementation of IInstanceProvider
public object GetInstance(InstanceContext instanceContext)
{
return GetInstance(instanceContext, null);
}
public object GetInstance(InstanceContext instanceContext, Message message)
{
return _container.Resolve(_serviceType);
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
if (instance is IDisposable) ((IDisposable)instance).Dispose();
}
#endregion
}
Y luego creamos el atributo con el que marcaremos los servicios WCF que necesiten inyección de dependencias…
public class UnityDependencyProviderServiceBehavior : Attribute, IServiceBehavior
{
#region Implementation of IServiceBehavior
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
public void AddBindingParameters(ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase,
Collection<ServiceEndpoint> endpoints,
BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (var dispatcher in serviceHostBase.ChannelDispatchers.OfType<ChannelDispatcher>())
{
dispatcher.Endpoints.ToList().
ForEach(endpoint =>
{
endpoint.DispatchRuntime.InstanceProvider = new UnityDependencyProvider(serviceDescription.ServiceType);
});
}
}
#endregion
}
"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…” (Gracias Mark) 
Los test…
El problema de los test está en que no tenemos un evento al cual nos podamos subscribir ni interfaz que implementar… Entonces, ¿Cómo creo los test sobre el IoC Container? by Scott…
Basados en las interfaces IA, IB y las clases A y B que escribimos en el artículo anterior, tendríamos los siguientes test:
[TestClass]
public class IocTest
{
private readonly IUnityContainer _ioc;
/// <summary>
/// En los test, este es mi punto de entrada (Composition root)
/// </summary>
public IocTest()
{
_ioc = UnityContainerFactory.GetContainer();
}
[TestMethod]
public void TestCreateObjetWithoutConstructorParameters()
{
var a = _ioc.Resolve<IA>();
Assert.IsNotNull(a);
Assert.AreEqual(1, a.ObjectId);
}
[TestMethod]
public void TestCreateObjetWithConstructorParameters()
{
//var a = new A(); Ya no necesitamos hacer esto...
//el framework de IoC se encarga de construir IA
var b = _ioc.Resolve<IB>();
Assert.IsNotNull(b);
Assert.AreEqual(1, b.ParamInjector.ObjectId);
}
}
Los elementos de configuración, ya podemos inyectarlos tal y como nos pedía Juanma:
[TestClass]
public class ConfigTest
{
private readonly IUnityContainer _ioc;
public ConfigTest()
{
_ioc = UnityContainerFactory.GetContainer();
}
[TestMethod]
public void TestConfiguration()
{
var global = new Global(new AppSettingsHelper());
var settings = global.Settings;
Assert.AreEqual("My Project DDD", settings.Name);
Assert.AreEqual("es-ES", settings.LanguageDefault);
Assert.AreEqual("dd-MM-yyyy HH:mm", settings.DateTimeFormat);
Assert.AreEqual(1, settings.TimeZoneOffset);
Assert.IsInstanceOfType(global.SettingsHelper.GetBoolean("bool"), typeof(bool));
}
[TestMethod]
public void TestIocConfiguration()
{
var global = _ioc.Resolve<IGlobalSettings>();
Assert.IsNotNull(global);
Assert.IsNotNull(global.Settings);
Assert.IsNotNull(global.SettingsHelper);
Assert.IsInstanceOfType(global.Settings, typeof(AppConfigurationElement));
Assert.IsInstanceOfType(global.SettingsHelper, typeof(AppSettingsHelper));
}
}

Gracias a Unai y a Eduard por hacer posible esta mejora…
PD: Aún no he probado los módulos implementados para MVC3 o para WCF… ya os contaré 
Salu2
En el artículo anterior implementamos todas las interfaces necesarias para usar algunos elementos de configuración a nivel de aplicación. Entre estos elementos estaba el Framework de IoC.
En ese mismo artículo explicábamos por qué decidimos inyectar al Framework de dependecia, así que hoy nos dedicaremos a implementar todas las interfaces y realizar algunos test.
Antes de empezar, deciros que he realizado una pequeña modificación a la interfaz IContainerConfiguration que vimos en el artículo anterior. Soy de los que cree que cuando algún código (mio o no) queda digno de “admirar” (lo cual no quiere decir “correcto”
), me quedo rato mirándolo aún días o semanas después de haberlo implementado. Esto, además de parecer que pierdo el tiempo, me ayuda a ver posibles refactoring que en su momento no vi.
En uno de esos momentos de “bobería” 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.
IContainerConfiguration ahora quedaría así:
public interface IContainerConfiguration
{
Type IocObjectType { get; }
}
Después de hecho el cambio, entramos en materia.
Pensando con el corazón y no en el performance, voy a utilizar como Framework de inyección de dependencia el Unity de Microsoft, pero recuerden, de la forma que lo hemos implementado podríamos usar cualquiera siempre que implementemos la interfaz IContainer.
Para temas de configuración, usaré el archivo de configuración de la aplicación. Al igual que el framework de IoC, podríamos obtener la configuración de cualquier otro lado tan solo implementando las distintas interfaces.
Empezamos con la implementación del UnityContainer, nuestro único requerimiento es implementar la interfaz IContainer.
public sealed class UnityContainer : IContainer, IDisposable
{
private readonly Microsoft.Practices.Unity.UnityContainer _container;
public UnityContainer()
{
_container = new Microsoft.Practices.Unity.UnityContainer();
}
#region Miembros de IContainer
public void InitializeContainer()
{
var section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Configure(_container);
}
/// <summary>
/// Retorna una nueva instancia del tipo T usando IoC
/// </summary>
/// <typeparam name="T">Tipo del nuevo objeto a instanciar</typeparam>
/// <returns>Instancia del tipo generico T</returns>
public T GetInstanceOf<T>()
{
return _container.Resolve<T>();
}
/// <summary>
/// Retorna una nueva instancia del tipo T usando IoC
/// </summary>
/// <typeparam name="T">Tipo del nuevo objeto a instanciar</typeparam>
/// <typeparam name="TParamType">
/// Un parámetro de tipo TParamType que se le pasa al construnctor de T
/// </typeparam>
/// <returns>Instancia del tipo generico T</returns>
public T GetInstanceOf<T, TParamType>(TParamType paramInjection)
{
_container.RegisterInstance(typeof(TParamType), paramInjection);
return _container.Resolve<T>();
}
#endregion
#region Miembros de IDisposable
/// <summary>
/// El Objeto UnityContainer del EnterpriseLibrary implementa IDisposable.
/// Al construir una instancia de este objeto dentro de nuestra clase, necesitamos
/// implementar dicha interfaz.
/// </summary>
public void Dispose()
{
_container.Dispose();
}
#endregion
}
La idea no es entrar a analizar el UnityContainer de Microsoft, sino me gusta, uso otro y nada cambia en toda mi aplicación. De cualquier forma, por detallar un poco la implementación de la interfaz, vemos la inicialización de Unity en el método que provee la interfaz (InitializeContainer), luego usamos el Container para satisfacer los dos métodos de la interfaz que retornan una instancia de un objeto basado en su interfaz (con o sin parámetro) y todo listo.
¿Hacemos entonces unos Test a ver qué tal? Ah no, que no puedo, primero tengo que implementar todo el tema de configuración. Pues lo que adoro de esta arquitectura es precisamente esto, sí, tengo que implementar el tema de configuració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ón. 
class UnityConfiguration : IContainerConfiguration
{
#region Implementation of IContainerConfiguration
public Type IocObjectType
{
get { return typeof(Project.IoC.EnterpriseLibrary.UnityContainer); }
}
#endregion
}
Aquí implemento la interfaz de configuración para el IoC y retorno directamente el tipo que implementa el IContainer. (Nota: El tipo UnityContainer que retorno aquí no es el de Microsoft, es el mío que implementa la interfaz IContainer).
Voy a crearme unos objetos bien simples para realizar los test
public interface IA
{
int ObjectID { get; }
}
public interface IB
{
IA ObjectInjection { get; }
}
public class A : IA
{
public A()
{
ObjectID = 1;
}
#region Implementation of IA
public int ObjectID { get; private set; }
#endregion
}
public class B : IB
{
public B(IA paramInjection)
{
ObjectInjection = paramInjection;
}
#region Implementation of IB
public IA ObjectInjection { get; private set; }
#endregion
}
Configuramos el Unity de Microsft para crear los Alias y los mapeos y vamos por los test.
<configSections>
<section name="unity"
type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
Microsoft.Practices.Unity.Configuration" />
</configSections>
<unity>
<typeAliases>
<typeAlias alias="IA" type="Solution.Test.Infrastructure.IoC.IA, Solution.Test" />
<typeAlias alias="IB" type="Solution.Test.Infrastructure.IoC.IB, Solution.Test" />
<typeAlias alias="A" type="Solution.Test.Infrastructure.IoC.A, Solution.Test" />
<typeAlias alias="B" type="Solution.Test.Infrastructure.IoC.B, Solution.Test" />
</typeAliases>
<containers>
<container>
<register type="IA" mapTo="A" />
<register type="IB" mapTo="B" />
</container>
</containers>
</unity>
Los test:
[TestClass]
public class IocTest
{
private readonly IContainer _ioc;
public IocTest()
{
_ioc = new IocFactory().Create(new UnityConfiguration());
}
[TestMethod]
public void TestCreateObjetWithoutConstructorParameters()
{
var a = _ioc.GetInstanceOf<IA>();
Assert.IsNotNull(a);
Assert.AreEqual(1, a.ObjectID);
}
[TestMethod]
public void TestCreateObjetWithConstructorParameters()
{
var a = new A();
var b = _ioc.GetInstanceOf<IB, IA>(a);
Assert.IsNotNull(b);
Assert.AreEqual(1, b.ObjectInjection.ObjectID);
}
}
Me encanta este momento…

Bien, pasemos del sentimentalismo y la adoración del color verde del Success
y vayamos a la configuración. La implementación de la configuración del framework de IoC desde el archivo de configuración quedaría de la siguiente forma:
public class ContainerConfigurationElement : ConfigurationElement, IContainerConfiguration
{
[ConfigurationProperty("unityType", IsRequired = true)]
public string IocQualifiedName
{
get { return (string)this["unityType"]; }
set { this["unityType"] = value; }
}
public Type IocObjectType
{
get { return Type.GetType(IocQualifiedName); }
}
}
Recuerden que ya la propiedad que nos da el QualifiedName no pertenece a la interfaz, sin embargo sí que la implementamos cuando queremos obtener quién será nuestro Framework de IoC desde la configuración.
Hagamos lo mismo para los Settings de mi aplicación:
public class AppConfigurationElement : ConfigurationElement, IAppConfigurationElement
{
#region Implementation of IAppConfigurationElement
[ConfigurationProperty("name", IsRequired = true)]
public string Name
{
get
{
return (string)this["name"];
}
set
{
this["name"] = value;
}
}
[ConfigurationProperty("datetimeFormat", IsRequired = false, DefaultValue = null)]
public string DateTimeFormat
{
get
{
var dtFormat = (string)this["datetimeFormat"] ??
new CultureInfo(LanguageDefault, false).DateTimeFormat.ToString();
return dtFormat;
}
set
{
this["datetimeFormat"] = value;
}
}
[ConfigurationProperty("languageDefault", IsRequired = true)]
public string LanguageDefault
{
get
{
return (string)this["languageDefault"];
}
set
{
this["languageDefault"] = value;
}
}
[ConfigurationProperty("timeZoneOffset", IsRequired = false, DefaultValue = 0D)]
public double TimeZoneOffset
{
get
{
return (double)this["timeZoneOffset"];
}
set
{
this["timeZoneOffset"] = value;
}
}
#endregion
}
Ahora ya podemos implementar la interfaz que agrupa los elementos de configuración.
public class AppConfigurationSection : ConfigurationSection, IAppConfigurationSection
{
[ConfigurationProperty("Setting")]
private AppConfigurationElement ConfigSettings
{
get
{
return (AppConfigurationElement)this["Setting"];
}
set
{
this["Setting"] = value;
}
}
[ConfigurationProperty("IocConfiguration")]
private ContainerConfigurationElement ConfigIocConfiguration
{
get { return (ContainerConfigurationElement)this["IocConfiguration"]; }
set { this["IocConfiguration"] = value; }
}
#region Implementation of IAppConfigurationSection
public IContainerConfiguration IocConfiguration
{
get { return ConfigIocConfiguration; }
set { ConfigIocConfiguration = (ContainerConfigurationElement) value; }
}
public IAppConfigurationElement Settings
{
get { return ConfigSettings; }
set { ConfigSettings = (AppConfigurationElement) value; }
}
#endregion
}
Vean que hemos tenido que definir propiedades que retornen un ConfigurationElement. Esto es requerido para poder leer las configuraciones del archivo de configuración, pero yo en ningún momento deseo que esos tipos sean conocidos por mi aplicación (recuerden que trabajamos ajenos a la tecnología que usemos). Es por eso que esta clase crea las propiedades concretas para la configuración como privadas y, las que usará mi aplicación (públicas) retornan la interfaz del tipo creado.
Por último, implementamos IGlobalSettings. Aquí me implemento un Singleton a nivel de aplicación para acceder a mi configuración. Dos razones, tengo un único punto de acceso (por eso el síngleton) y los datos que guarda mi configuración no cambian durante todo el ciclo de vida de la aplicación (por eso digo que es a nivel de aplicación)
public sealed class Global : IGlobalSettings
{
/// <summary>
/// Singleton. Thread safe.
/// </summary>
private static readonly Lazy<Global> _instance = new Lazy<Global>(() => new Global());
/// <summary>
/// IocFactory.
/// </summary>
private readonly IContainer _ioc;
private Global()
{
var cfg = (IAppConfigurationSection)ConfigurationManager.GetSection("Project");
_ioc = new IocFactory().Create(cfg.IocConfiguration);
Settings = cfg.Settings;
}
public static Global Application
{
get { return _instance.Value; }
}
#region IAppConfigurationSection Members
public IContainer Ioc { get { return _ioc; } }
public IAppConfigurationElement Settings { get; private set; }
#endregion
}
Ya podemos ir a por los Test de configuración. El IoC ya lo probamos, por lo que con saber que el tipo retornado por la configuración es correcto (implementa IContainer), tengo suficiente
Antes de escribir los test, creamos la configuración en el archivo de configuración de la aplicación.
<configSections>
<section name="Project"
type="Project.Settings.Config.AppConfigurationSection, Project.Settings.Config"
requirePermission="false" />
</configSections>
<Project>
<Setting name="My Project DDD"
languageDefault="es-ES"
datetimeFormat="dd-MM-yyyy HH:mm"
timeZoneOffset="1" />
<IocConfiguration unityType="Project.IoC.EnterpriseLibrary.UnityContainer,
Project.IoC.EnterpriseLibrary" />
</Project>
y ahora sí…
[TestClass]
public class ConfigTest
{
[TestMethod]
public void TestConfiguration()
{
var settings = Global.Application.Settings;
Assert.AreEqual("My Project DDD", settings.Name);
Assert.AreEqual("es-ES", settings.LanguageDefault);
Assert.AreEqual("dd-MM-yyyy HH:mm", settings.DateTimeFormat);
Assert.AreEqual(1, settings.TimeZoneOffset);
}
[TestMethod]
public void TestIocConfiguration()
{
var ioc = Global.Application.Ioc;
Assert.IsInstanceOfType(ioc, typeof(Project.IoC.EnterpriseLibrary.UnityContainer));
}
}
Result:

y Chirrin-chirran…. 
¿Por dónde empezamos hoy? Pues si conocemos de antemano la arquitectura DDD, sabremos que uno de los aspectos más importante en su implementación es la inyección de dependencia.
El concepto de aplicaciones orientadas al dominio explica claramente que debemos aislar la lógica del dominio de cualquier tipo de detalle técnico.
La “Guía de arquitectura N-capas orientada al dominio” nos dice…
“Esta capa debe ser responsable de representar conceptos de negocio, información sobre la situación de los procesos de negocio e implementación de las reglas del dominio. También debe contener los estados que refleja n la situación de los procesos de negocio, aun cuando los detalles técnicos se delegan a las capas inferiores….”
Resumiendo un poco, el dominio debe saber “Qué” se hace, pero nunca “Cómo” se hace…
Por otro lado, el concepto de una interfaz es un contrato que indica lo que se debe hacer, pero nunca incluye código de cómo se debe hacer… De aquí, que la forma de aislar el dominio en una arquitectura DDD de su implementación, sea mediante interfaces.
La importancia de la inyección de dependencia en este tipo de arquitectura es precisamente esta, inyectar instancias de objetos que saben “cómo” hacer algo mediante interfaces que indican “qué” se debe hacer. Es lógico que los objetos que se inyecten deban implementar la interfaz, pero si no lo hacen ya se encargará el framework de avisarnos con un ruidoso error. 
Para usar inyección de dependencia existen muchos frameworks. Algunos de ellos son:
- Ninject
- Unity
- Castle.Windsor
- Autofac
- StructureMap
Aquí encontraras un buen debate sobre cuál es mejor o peor o cuáles son sus ventajas o desventajas.
http://stackoverflow.com/questions/4581791/how-do-the-major-c-sharp-di-ioc-frameworks-compare
A mí en esta parte siempre me entra la duda, si hablamos de un dominio que no es afectado por los detalles técnicos entonces, ¿debería preocuparme por saber cuál debe ser el Framework que usaré para inyectar dependencias? Bueno, tampoco pasemos olímpicamente de esto, claro que debía preocuparme por temas de performance… pero estos frameworks evolucionan y el que es mejor hoy, mañana puede ser peor.
¿Qué hago entonces? ¿Pues no les gustaría poder inyectar a quien te inyecta? ¿Nunca han querido pagar con la misma moneda? Yo decidí inyectar el framework de inyección… 
De lo que hemos visto, el objetivo para mí de un Framework de inyección de dependencia es precisamente retornarme una instancia de un objeto mediante su interfaz. Entonces, lo que necesito sería algo como esto:
public interface IContainer
{
void InitializeContainer();
T GetInstanceOf<T>();
T GetInstanceOf<T, TParamType>(TParamType paramInjection);
}
Ahora necesito algún elemento de configuración que me indique cómo instanciar mi framework de IoC. ¿De dónde sale la configuración? Pues no lo sé, lo que realmente me importa es su contrato, no cómo lo haga. La interfaz para la configuración contiene una propiedad que me retorna el QualifiedName usado para crear el tipo concreto del framework de IoC.
public interface IContainerConfiguration
{
string IocQualifiedName { get; set; }
Type IocObjectType { get; }
}
Para combinar el Container con su configuración nos implementamos un Factory:
public sealed class IocFactory
{
public IContainer Create(IContainerConfiguration cfg)
{
var container = (IContainer)Activator.CreateInstance(cfg.IocObjectType);
container.InitializeContainer();
return container;
}
}
Hasta aquí ya tenemos definidas las interfaces… pero ¿quién implementa estas interfaces? y lo más importante, ¿cómo se usaría al final?
Cada aplicación que hago, “debería” tener aspectos que son generales a nivel de toda la aplicación. Me refiero a parámetros cómo:
- Formato de fecha que usaré por defecto
- Idioma que usaré por defecto
- Zona horaria en que se encuentra la aplicación
Estos pará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ón está en América o el viejo continente, por eso predefino este tipo de datos. A estos parámetros se suma ahora mi Framework de IoC, que también será de uso general por toda la aplicación.
Cómo hemos repetido durante todo el artículo, en este punto no sé de dónde saldrá esta información. A algunos les será más útil sacarlo de base de datos y a otros del archivo de configuración de la aplicación, así que sigo creando interfaces.
public interface IAppConfigurationElement
{
string Name { get; set; }
string DateTimeFormat { get; set; }
string LanguageDefault { get; set; }
double TimeZoneOffset { get; set; }
}
Esta interfaz define los parámetros generales de mi aplicación. En la siguiente interfaz, combinamos estos parámetros de configuración con la interfaz de IoC.
public interface IAppConfigurationSection
{
IAppConfigurationElement Parameters { get; set; }
IContainerConfiguration Ioc { get; set; }
}
Finalmente combinamos las interfaces que darán a nuestra aplicación los parámetros que hemos definido y el Framework de IoC que usaremos
public interface IGlobalSettings
{
IContainer Ioc { get; }
IAppConfigurationElement Parameters { get; }
}
Con esto mejor cerramos el artículo de hoy, creo que me he pasado de largo
así que dejamos la implementación y los test para otro día…
Hasta la próxima...
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á haciendo estará bien o será un simple disparate. 
Partiendo de esta duda, el objetivo de esta serie no es crear una guía para orquestar una arquitectura DDD, ni siquiera pretendo que sea un modelo a seguir. Mi objetivo es más bien ir compartiendo por aquí 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.
Sin más, empiezo por donde se empieza cualquier arquitectura
El diagrama de capas:

Esta parte es la que casi siempre tengo clara… La distribución de las capas en Dominio, Aplicación, Infraestructura, la capa de servicios WCF (opcional) y las interfaces de usuario, cada una con su flujo de información.
No quiero entrar a analizar qué 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ón entre la interfaz de usuario y el dominio. Este flujo se ve en muchas arquitecturas que muestran inyección de dependencia de los repositorios dentro de los controladores de un proyecto MVC (incluso ASP.NET MVC está preparado para inyectar dependencias a los controladores). En este caso, no vamos a tener ese flujo y es por eso que no lo represento.
¿Por qué? Hoy en día es poco habitual que desarrollemos una sola aplicación, normalmente nuestros proyectos requieren que para un mismo dominio tengamos varios frentes por el que lo atacamos (UI para móviles, UI para desktop, servicios que expongan funcionalidad a terceros, etc.). Con el objetivo de centralizar la lógica de aplicación (servicios en la capa aplicación) y permitir la reutilización de código, es que ninguna interfaz de usuario llega al dominio si no es mediante la capa de aplicación.
En Visual Studio cada capa está definida como un “Solution Folder”, por lo que la estructura de mi arquitectura queda más o menos así…

Creo que se ve que existen 12 proyectos dentro de la solución, por lo que el desarrollo va mucho más adelantado que esta serie de artículos. Espero a medida de que el tiempo me lo permita, ir poniéndome al día… pero sobre todo, espero que se diviertan tanto como yo... 
Salu2
Primero que todo disculparme si alguien entra en este post pensando que voy a hablar de política :P siento que no sea así. Ya me sobra con el regaño que me dieron ayer por decir que “insidiar” era un verbo. ;)
Entrando en la materia que nos ocupa… 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ía sin nada que hacer e intentando complicarnos la vida y, nada más lejos de la realidad. La arquitectura de un proyecto puede muchas veces llevarnos a escribir un mal código.
Ayer a un colega le pasó 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ón de control, Inyección de dependencias, etc… todo esto puede ocasionar un retraso en el proyecto que nadie está de acuerdo en asumir.
Para evitar todo esto, diseñó 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 le permitiera en un momento dado, dar el cambio definitivo a arquitecturas verdaderamente orientadas al dominio.
Ayer se le presentó una problemática, necesitaba mandar a encender desde un panel de administración un conjunto de dispositivos por un tiempo determinado. Ya tenía funcionando toda la lógica de encendido y solo debía insertar el nuevo requerimiento de definir el tiempo que dicho dispositivo iba a permanecer encendido. La secuencia para encender dispositivos era la siguiente:

Con el nuevo requerimiento la secuencia quedó de la siguiente manera:

La solución dada no me gustó porque rompe con la naturaleza propia del método, se está actualizando estados en un método destinado a seleccionar. Esto evita que dicho método pueda ser reutilizado para lo que fue pensado, traer un listado de dispositivos.
Cuando le dije cómo lo hubiera hecho yo, el diagrama de secuencia quedó de la siguiente forma:

Ummm… ¿Qué pasa aquí? Yo viajo al dominio mediante los servicios WCF dos veces para realizar una acción. Al final, él pensó una solución que desde el punto de vista de arquitectura está mal, pero es mucho más eficiente que la mía.
¿Por qué nos pasa esto? Si miramos el último diagrama de secuencia vemos como si algo faltara en la arquitectura que permita hacerlo bien y además que sea eficiente. Si me llevo esto a DDD ¿cómo queda?
Diagrama de secuencia:

Feliz y contento… toda la lógica que estaba en el UI ahora pasa a mi capa de aplicación, por lo que solo viajaría una vez por la capa de servicios WCF y todo lo que está dentro del ApplicationLayer, podría ser reutilizado desde otros UI.
Nada, que llegamos a la conclusión que… es la hora del cambio J
Salu2
En el proyecto en el que me encuentro actualmente (equipo de 4 personas) hemos logrado poner en práctica toda la teoría conocida sobre SCRUM. Algunas aplicadas 100% según la documentación, otras, adaptadas a los requerimientos del proyecto en sí.
Esto no es nuevo, todos sabemos que la guía para el desarrollo ágil existe, podemos aprender y usar de ella todo lo que enseña, pero al final… cada proyecto es un libro aparte que se escribe a su forma y bajo sus propios requerimientos.
Uno de los puntos que no puede faltar (adaptado o no) en un desarrollo ágil es el Daily Stand-Ups. Esas reuniones de 15 minutos en las que intercambiamos qué hacemos, qué hemos hecho y qué problemas tenemos.
Este tipo de reunión está definida en el desarrollo SCRUM de la siguiente manera:
Daily Stand-Ups (Scrums)
During a sprint, the team, the ScrumMaster, and the product owner (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.
At the meeting, each team member answers the following three questions:
• What have you done since yesterday?
• What are you planning to do today?
• 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.)
La aplicación de este tipo de reuniones dentro de un proyecto crea un entorno de trabajo sumamente favorable. Todos conocemos qué ha hecho o qué está haciendo cada miembro del equipo, todos aportamos solució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í, son detectados muy pronto y permite a su vez, darle una pronta solución.
A grandes rasgos, el problema sobre qué hace cada miembro del equipo estaba resuelto. Todos éramos capaces, sin pérdida alguna de tiempo, de asumir o colaborar con la tarea de otro. Pero… (Grrrrrr!!!... siempre hay peros)
Nos dimos cuenta que algo más detallado se nos estaba escapando. Cada tarea asignada a un miembro del equipo normalmente está compuesta por Bugs, Tasks, o Issues. La solución a nivel de código que se daba a cada elemento muchas veces no contaba con la calidad suficiente, o simplemente no se aplicaba una solución que pudiera ser reutilizable. A este nivel de detalle en los Daily Stand-ups, no llegábamos.
Una primera solución fue enviarnos un correo al final del día en el que cada uno contábamos qué había hecho (a nivel de Bugs, Tasks o Issues) hablando un poco de la solución implementada en cada caso, pero ( y más peros…) Somos informáticos, odiamos trabajar de más :D y, escribir este correo a final del día iba a terminar perdiéndose.
Pensando un poco en el correo y la información que recogíamos nos dimos cuenta que esto al final era lo mismo que mirar toda la actividad realizada durante el día en el TFS (Team Fundation Server) ¿Por qué entonces no preguntarle al TFS lo que cada miembro del equipo había hecho durante el día? Incluso, ¿Por qué no preguntarle al TFS lo que había hecho por sí solo durante el día? (Builds de integración continua fallidos, Works Items creados, etc.)
Si pudiéramos tener acceso al TFS desde internet, la solución hubiera sido más simple, pero en la mayoría de los casos esto no es así. Al final, desarrollamos una tarea que recoge toda la información del TFS realizada en el día y nos envía un resumen por correo :)
La solución nos pareció interesante y por si pudiera ser reutilizada por alguien más, la publicaremos acá en cuanto le apliquemos un poco de Refactoring y le pongamos una cara bonita.

Hola a todos...
El martes 20 de septiembre, que es el martes próximo (mañana no, el próximo… o sea… la semana que viene… en fin, que me lío) :-p, daré un evento con los chicos de SNUG sobre ADO.NET
De ADO.NET hay mucha información, libros, eventos, blogs en Internet que contienen material excelente sobre toda la arquitectura, clases, métodos, propiedades y eventos que lo componen.
Para no hacer de este evento uno más de esos tantos, nos vamos a centrar en las buenas prácticas ¿qué debemos y qué no debemos hacer cuando usamos ADO.NET? Esto no quiere decir que no expliquemos su arquitectura o no vayamos a contar qué es un Command, Connection o DataReader, solo que no nos quedaremos ahí, sino que profundizaremos con ejemplos (Visual Studio 2010 + C#) cómo poner en un proyecto real toda esa información.
Espero verlos ahí, y que aprendamos que no solo usando la última moda como Entity Framework, Linq2Sql o NHibernate, podemos tener buenas prácticas en nuestros desarrollos.
La URL de registro para el evento es esta: https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032493902&Culture=es-ES

Nos vemos ;)
Hola...
Al fin después de algún tiempo renovando todo el código de este proyecto, logro que esté online.
La idea surgió en un evento de SNUG sobre internacionalización de aplicaciones en el que se mostró una aplicación que permitía leer archivos de recursos (resx). La aplicación usaba Bing para realizar la traducción a un idioma seleccionado y visualizaba el resultado. (Estaba hecha en Windows Form).
Al verla, nos gustó la idea pero llevando su funcionalidad a la WEB. Ya en la WEB, pensamos si no sería mucho más interesante obtener la traducción de Bing y de Google y así poder seleccionar de las dos, la más acertada. Aun así, algunas traducciones de Google o Bing podrían no ser correctas, así que decidimos permitir editar la columna de resultados para incluir nuestra propia traducción. Para finalizar, nada más lógico que permitir descargar el archivo de recurso ya traducido al idioma seleccionado…
Así surgió resXgen http://resxgen.odelvalle.com/
Hay un botón de demo que carga un archivo de recurso que tenemos en la aplicación, de todas maneras, cualquiera puede subir un archivo de recurso, seleccionar el idioma en que se encuentra y probar.
Aún está en Beta y, entre las cosas más importantes que quedan por hacer, es escribir una ayuda o guía para su utilización.
Para reportar cualquier problema o sugerencia he montado un Mantis http://mantis.odelvalle.com/ donde podremos darle seguimiento.
Tratadla suave que aún está de estreno…
Hola
Me voy a saltar el post pendiente que tengo sobre crear o comentar algún código existente sobre el algoritmo Hi/Lo para los Object ID en Entity Framework. El culpable de este salto es un inquieto colega de proyecto que se puso a probar un artículo que publicamos hace unos días por Twitter sobre MVC 3 con Repositorios e inyección de dependencias usando Entoty Framework.
El artículo no permite descargar el código del ejemplo, así que, gracias Oscar por ahorrarme el trabajo
Después del prólogo y los agradecimientos, entramos en materia.
El problema, si le podemos llamar así, ya lo tenía anotado como uno de los temas a tratar en esta nueva aventura con Entity Framework. El código causante de todo el debate es este:

La parte que nos importa en la clase Db, la cual hereda del contexto, es la implementación del constructor que llama a la base pasando como parámetro la cadena “DemoDb2”. El parámetro que se le pasa al contexto, según el MSDN, identifica la cadena de conexión o el nombre de la base de datos asociada al modelo que vamos a usar. Este simple código, si no conoces qué hace Entity Framework con él, nos puede costar un “poquito de dolor de cabeza”. 
Supongamos que vamos a nuestro archivo de configuración y definimos la siguiente cadena de conexión (Observe que he puesto “DemoDb” y no “DemoDb2”)

…o simplemente olvidamos que debemos configurar el web.config para indicar la cadena de conexión. Ejecutamos y “walaaa”
Nuestra aplicación funciona

Si voy a mi servidor en busca de la base de datos me encuentro con que no existe. Pues bien, si EF no encuentra la cadena de conexión o la misma es incorrecta, utiliza el SQL Express que tengamos instalado en local y con autenticación integrada de Windows, crea la base de datos.

Les juro que no estoy haciendo trampas, ninguna de las bases de datos que están tachadas es la del ejemplo 
En mi opinión, hubiera preferido que ocurriera un error y así darme cuenta que tenía algo mal, digamos que algo así...


Editado: En los comentarios, Pablo Núñez nos dice cómo lograr que EF pueda tener el mismo comportamiento que NH. (Gracias Pablo)
Hola
Hace poco me he comprado el excelente libro de Entity Framework 4.1. He leído mucho sobre este ORM desde sus primeras versiones, pero nunca me resultó lo suficientemente atractivo para usar en un proyecto real sobre el cual me permitieran elegir. Como alternativa a EF tenía NHibernate, ORM que también he usado desde hace mucho tiempo y sobre el cual no tengo dudas en cuanto a funcionalidad o limitaciones que me pueda encontrar.
Entendiendo que no siempre se puede elegir, y por los muchos comentarios que ha generado la nueva versión de EF 4.1 (y más por la posibilidad real de no tener atadas las entidades al ORM) decidí de una vez enfrentarme a él de manera seria, pero es inevitable hacer comparaciones (aunque no sean buenas)
Aclaro que mi intención jamás sería, ni por asomo, criticar a este excelente ORM, más bien esta serie de artículos va por el camino de conocer bien hasta dónde llegan mis limitaciones en su utilización.
Los Object ID.
Desde cualquier aplicación orientada al dominio se enfoca mucho la necesidad, que yo llamaría obligació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ág. 78) cuando dice: – “Primero el modelo por favor”. :)
Siguiendo tan buen consejo me voy a Visual Studio dispuesto a seguir el ejemplo descrito en el libro empezando por la entidad “Autor”.

Me detengo en esta ventana en la que remarco la propiedad “Key Property”. ¿Qué 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.
La definición de Object ID está explicada en Mapping Objects To Relational Databases de Scott W. Amble.
“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”
Yo creo que la definición ni siquiera necesita traducción :)
Algunas funcionalidades de los OID coinciden con su “homólogo” en el modelo relacional. Por ejemplo, mantener y simplificar la relación entre entidades (joins entre tablas en el modelo relacional). Uno de los errores más comunes cuando definimos el modelo es cuando asignamos una responsabilidad al OID dentro del dominio. Los OID NO pueden tener ningún significado lógico “Nada, Zip, Zilch, Zero” :P Como dice Scott, toda propiedad que interviene en un modelo con un significado dentro del dominio puede ser potencialmente cambiada. Un OID, no.
Regresando a EF 4.1 (que me pierdo) creo mi entidad y me decido a seleccionar mi estrategia para el OID dentro del modelo.

Pues vaya sorpresa :"( solo tengo 3 opciones como estrategia para generar mi OID. ¿Cuál de estas tres opciones puedo elegir?
MSDN dice:
Computed - Un valor generado para INSERT y para UPDATE. o_0 No me he puesto a pensar en qué casos me puede ser útil esta estrategia, ahora mismo no me imagino ninguna porque si el OID cambia durante su ciclo de vida, rompe con su condición de ser único e invariable.
Identity - 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. ¿Por qué el identity de SQL no es para mí una estrategia válida? Pues Scott lo deja claro cuando dice “An OID should be unique within a class hierarchy, and ideally unique among all objects”
El identity puede generar un mismo valor dentro del modelo para dos entidades distintas y esto rompería también con la definición “ideal” del OID, además, no me vale en absoluto en un sistema distribuido (en un clusters por ejemplo).
None - 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ía tan complejo como se pueda imaginar. Aunque sería la única alternativa y por suerte, hay algoritmos que nos permiten no entrar en polémicas con los bloqueos
NHibernate por su parte propone para los OID las siguientes estrategias : Increment, identity, sequence, hilo(Mi Favorito), seqhilo, uuid.hex, uuid.string, guid, guid.comb, native, assigned y foreign. Las puedes encontrar todas explicadas aquí
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á el OID hasta que no se guarden los cambios (Si no lo generamos nosotros).
Mi próximo paso en esta serie será 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 único valor. A cada cliente se le asigna un valor Hi y, con un rango de valores Low formaría un identificador único para todo el modelo. Esto garantiza que varios clientes siempre utlizarán valores distintos para los nuevos OID creados y evitaríamos los temas de bloqueos.
¿cómo resuelven esta "limitación" cada uno de los que actualmente usan EF? ;)
Hola de nuevo, hoy ando de nostálgico revisando "viejos" documentos :)
Este es uno de los que más me gusta... Patrón iterator, creado al igual que el anterior para el mismo curso de patrones. Les dejo el documento adjunto.
Salu2
Hola,
Hoy en día, en muchas de las arquitecturas de moda escuchamos hablar de un patrón muy utilizado llamado "Command". ¿Sabemos con claridad lo que es el patrón Command?
Para quien aún no lo tenga tan claro les dejo un documento creado para un curso de patrones en el MUG de Argentina en el año 2004. Espero les ayude a entender un poquito más a este excelente y tan utilizado patrón.
Salu2
En estos días parece haber un BOM de análisis sobre pruebas unitarias, sobre metodologí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í que como ya es costumbre en estos casos no se puede hacer mención de nombres de empresas o detalles del proyecto. Bueno, me chivo un poco: X no es española... :)
Llegamos al cliente con un objetivo. Se estaba preparando una demo por una empresa X sobre un conjunto de servicios novedosos que podrí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ía todo el guión interactuaba con los sistemas, además, el objetivo de la empresa X era vender la idea, pero en ningún caso llevar dicho proyecto a un entorno interactivo o permitir que aquello sirviera de base para continuar posibles desarrollos de ideas. Aquí entrabamos nosotros.
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ía.
La empresa X con su idea clara de DEMO guiada, optó por el siguiente modelo de desarrollo.

Sin muchas complicaciones. Tenían múltiples funcionalidades concentradas en una misma aplicación WEB construidas sobre MVC. Para cada funcionalidad tenían un único controlador desde el que interactuaban con la base de datos (donde fuera necesario) usando directamente linq2sql.
Nuestro objetivo estaba bien marcado, cambiar todo eso y convertirlo en algo sostenible desde el punto de vista de arquitectura, pero ¿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 ¿qué se podía hacer?
Teníamos los siguientes problemas:
- Los requerimientos se les pedían directamente a la empresa X
- La empresa X siempre iba a estar evolucionando la DEMO con los nuevos requerimientos
- Mientras no finalizara la DEMO, nuestro trabajo iba a estar en un segundo plano. :'(
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ás si se trata de tu primer trabajo a un cliente importante. Había que lograr algo más…
Los problemas que podían tener los desarrolladores de la empresa X eran evidentes. Esos mismos problemas que tan comúnmente nos cuestionamos por estos tiempos. No quieren perder tiempo y desarrollan algo que es solo para mostrar, así que van a toda prisa y se olvidan que sea lo que sea que se construya, si no lo levantas desde una base sólida llegará el momento en que se convierta en algo insostenible.
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ás que regresar a la base y apuntalar todo lo que habías hecho para luego poder colocar las luces.
Con este análisis realizado nos trazamos un objetivo más ambicioso:
- Crear un entorno ágil de desarrollo: Esto era indispensable, necesitábamos trabajar rápido y con ciclos cortos de evolución. Todos debíamos conocer el trabajo de todos y los cuellos de botella que pudieran afectar el ritmo que deseábamos llevar, debían ser resueltos de inmediato. (Reuniones en la máquina del café de 15 min hasta tres veces al día) :P
- Una arquitectura organizada que nos permitiera identificar rápidamente los problemas y solucionarlos afectando el menor código posible. Esto a su vez nos llevará a que aplicar nuevos requerimientos sea sencillo y rápido de realizar. Con este objetivo separamos todas las funcionalidades en aplicaciones distintas pero manteniendo MVC y, creamos servicios WCF para cada aplicación. Los servicios WCF se comunicaban con un dominio único que nos permitía desde las distintas aplicaciones, reutilizar la lógica de desarrollada. (Una simple arquitectura de N capas)
- Mejoras de performance donde quiera que fuera posible. Este objetivo era menor, pero donde pudiéramos, debí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.
- Integración continua y test unitarios (todo y en todo momento, debía funcionar bien).
La arquitectura (a grandes rasgos) que nos propusimos fue la siguiente:

En principio estar en segundo plano era inevitable. Debíamos estar constantemente chequeando la DEMO para ver las nuevas evoluciones e implementar los cambios sobre nuestra arquitectura pero de manera correcta. Solo podíamos trabajar rápido y bien, el resto era simplemente esperar, darle tiempo al tiempo.
…y el tiempo pasó, y llegó lo que muchos no somos capaces de ver desde un principio. El cambio… Porque siempre, siempre hay cambios...
Aquí cometieron un nuevo error, pero que es muy comú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ía. No le puedes decir a un cliente que te demoras 1 mes en hacer un cambio. Entonces, ¿qué hicieron? La solución fue crear un camino nuevo para dar una respuesta rápida a los cambios. (copy + paste + hacer los cambios) Otra bomba por culpa del tiempo...
Pasó que los cambios no quedaron ahí, y vinieron más y más y se optó 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í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ía, demoraba más y más y más…
Y mientras del otro lado de la montaña... :) El tiempo nos sirvió para lograr dos cosas:
- Llegar a igualar nuestra funcionalidad a la que tenía la empresa X hasta el momento.
- Indagar sobre nuevas funcionalidades que no estaban incluidas en la DEMO y desarrollarlas
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í. El tiempo para realizarlos 4 días. Era lunes, el viernes se debían presentar para revisión…
La demo guiada que hoy se usa, es nuestra aplicación. :)
Pero, pero, pero... no escribo todo esto para decir que lo hemos hecho mejor. Estoy seguro que a muchos de ustedes se les ocurrirían estrategias mejores que la que nos planteamos. Lo dejo escrito, y de ahí el título de este post, para que vean que todo cuanto hacen, por muy DEMO que sea, si no se hace mí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ñando con metodologías, puede ser el peor enemigo de lo que estás haciendo.
Salu2 y suerte con las DEMO... ;)
Hola,
Hoy ando de inventos… ;)
Resulta que me he instalado la aplicación de Twitter para iPhone porque hace mucho tengo una cuenta en esta red social, pero también hace mucho que la tenía abandonada.
Mirando la aplicación echaba mucho en falta el poder publicar URL directamente desde el navegador del iPhone, pero buscando y buscando me encontré que en los settings de la aplicación para Twitter había una forma de hacer lo que quería.
Las instrucciones a seguir están en esta página:

Era crear un simple bookmark y luego editarlo para dejar solo el javascript. Esto estaba genial pero… las URL las publicaba a tamaño completo y esto para una red que solo permite 140 caracteres por post, es realmente un problema.
Mirando la forma en que lo hacían me di cuenta que lo que hacen es usar javascript para llamar a la aplicación de Twitter y le pasan el URL actual, o sea, el window.location.
La pregunta del millón era: ¿Qué pasa si antes de llamar a tweetie tomo la URL, la convierto a un formato pequeño (por ejemplo: tinyUrl) y luego se la paso a la aplicación de Twitter? ¿Cómo podría hacer algo así?
Pues bien… me froté las manos y empecé:
Me creo una página HTML sin más, incluyo una referencia a Jquery desde el CDN de Microsoft, y con jQuery en mano, todo es fácil :)))))
Mi página debe:
1- Tomar un parámetro que le pasarían, el cual sería el URL en el que se encuentra navegando el usuario
2- De alguna forma usar el servicio de TinyURL para convertir la URL a un formato pequeño
3- y finalmente pasar el resultado a Twitter.
¿Parece simple no? Aquí está el código:
<html>
<head>
<script type="text/javascript" src="http://ajax.microsoft.com/ajax/jQuery/jquery-1.5.1.min.js"></script>
<script type="text/javascript">
function makeTinyUrl(url)
{
$.getJSON('http://json-tinyurl.appspot.com/?url=' + url + '&callback=?',
function (data)
{
window.location = 'tweetie:' + data.tinyurl;
});
}
var urlParams = {};
var e,
a = /\+/g, // Regex for replacing addition symbol with a space
r = /([^&=]+)=?([^&]*)/g,
d = function (s) { return decodeURIComponent(s.replace(a, " ")); },
q = window.location.search.substring(1);
while (e = r.exec(q)) urlParams[d(e[1])] = d(e[2]);
makeTinyUrl(urlParams['tw']);
</script>
</head>
<body/>
</html>
Después de publicar mi página HTML en un servidor, el resto era fácil: Seguir los mismos pasos que dan en Atebits y probar… :)
Me cree un bookmark en el safari del iPhone con la siguiente URL:

y WALAAAA!!! Funciona!! :)))))
Quiero aclarar que esta URL solo la dejaré publica por un tiempo para que puedan probar, pero de ninguna forma es parte o se trata de un servicio público.
Salu2
Hola, antes de empezar, desearles a todos un feliz inicio de año y que el trabajo que realicen le haga posible hacer realidad todas las metas que se han trazado.
En el post de hoy vamos a ver cómo podemos servir imágenes mediante un ActionResult en MVC. La práctica de este mecanismo puede ser aplicado a servir imá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.
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.
Vamos allá…
Empezamos con el ejemplo más simple. Saquemos la imagen de la base de datos y la servimos a la WEB.
public class PhotoResult : ActionResult
{
public override void ExecuteResult(ControllerContext context)
{
var id = context.HttpContext.Request.QueryString["id"];
using (var uow = new UnitOfWork())
{
var photoBytes = (new CustomersDAC(uow).Load(id)).Photo.ToArray();
}
context.HttpContext.Response.ContentType = "image/png";
context.HttpContext.Response.BinaryWrite(buffer);
context.HttpContext.Response.Flush();
}
}
Sencillo, implementamos una clase que herede de ActionResult y sobre-escribimos el método ExecuteResult. En este método tomamos un parámetro “id” que nos enviarán por el QueryString y traemos de la base de datos una imagen que tenemos almacenada en forma de arreglo de bytes.
Cuando tenemos el arreglo de bytes lo escribimos en la respuesta que se envía al cliente e indicamos que el tipo de contenido es imagen y su formato es png.
Hasta aquí ya tenemos el ActionResult, ahora solo necesitamos un método en el controlador que nos retorne una instancia de PhotoResult.
public PhotoResult GetPhotoByCustomer()
{
return new PhotoResult();
}
Nada más… esto es todo lo que necesitamos para que el controlador ejecute nuestra acción y retorne la imagen al cliente. ¿Cómo lo invocamos?
<img alt="Your Photo" src="<%= Url.Action("GetPhotoByCustomer?id=1", "Home") %>" />
Cuando el browser hace el GET al servidor para obtener el src de la imagen, en nuestra aplicación esto será traducido a un Request al Método que tenemos dentro del controlador, el cual se encargará de retornarnos la imagen solicitada.
Otra aplicación que mencionamos al inicio del post y que puede tener esta manera de servir imágenes al cliente es cuando queremos modificar una imagen que ya tenemos almacenada en el sistema de archivos antes de mostrarla.
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ágenes que vamos a utilizar antes de subir al servidor.
El cambio para poder hacer lo anterior está solo en el ActionResult que implementamos. El resto de la implementación es exactamente igual.
public class CopyrightImageResult : ActionResult
{
private const string Copyright = "Copyright (c) Omar del Valle Rodríguez";
public override void ExecuteResult(ControllerContext context)
{
var imagePath = context.HttpContext.Server.MapPath("/images/Photo.PNG");
var mainImage = Image.FromFile(imagePath);
var memStream = new MemoryStream();
var fontCopyright = new Font("Arial", 12);
const float xCopyrightPoint = 493.0f;
const float yCopyrightPoint = 70.0f;
//create graphics from main image
using (var g = Graphics.FromImage(mainImage))
{
g.DrawString(Copyright, fontCopyright, Brushes.Black, xCopyrightPoint, yCopyrightPoint);
mainImage.Save(memStream, ImageFormat.Png);
}
var buffer = memStream.ToArray();
context.HttpContext.Response.ContentType = "image/png";
context.HttpContext.Response.BinaryWrite(buffer);
context.HttpContext.Response.Flush();
}
}
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.
Salu2 y hasta la próxima...
Hace poco pasé por la necesidad de enviar un formulario al servidor usando ajax en una aplicación MVC. El problema principal que tenía era que el formulario incluía un número “grande” de campos (o no tan grande pero resulta que soy un vago), por lo que no quería pasar el trabajo de tener que convertir todo eso a JSON como parámetros individuales. Tampoco deseaba, evidentemente, tener un método en el controlador al cual le llegaran 5 o más parámetros.
Pues bien… la vista en mi caso estaba diseñada para trabajar con un modelo definido por mí:
public class CustomerModel
{
public string UserName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Language { get; set; }
[DataType(DataType.Password)]
public string Password { get; set; }
[DataType(DataType.Password)]
public string ConfirmPassword { get; set; }
}
La vista:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<CustomerModel>" %>
Mi formulario:
<% using (Html.BeginForm()) { %>
<div>
<fieldset>
<legend>Customer Information</legend>
<div class="editor-label">
<%: Html.LabelFor(m => m.FirstName) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(m => m.FirstName) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(m => m.LastName) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(m => m.LastName) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(m => m.UserName) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(m => m.UserName) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(m => m.Password) %>
</div>
<div class="editor-field">
<%: Html.PasswordFor(m => m.Password) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(m => m.ConfirmPassword) %>
</div>
<div class="editor-field">
<%: Html.PasswordFor(m => m.ConfirmPassword) %>
</div>
<p>
<input type="button" onclick="uploadCustomerForm()" value="Register" />
</p>
</fieldset>
</div>
<% } %>
La solución ideal para mí 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ía que el método en mi controlador se viera así:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SaveCustomer(CustomerModel model)
{
return Content(string.Format("This is my content: {0}, {1}",
model.LastName, model.FirstName));
}
Después de mucho andar por los rincones oscuros del mundo Google, hallé una solución limpia, elegante y simple.
Mi script:
<script src="/Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
function uploadCustomerForm()
{
var data = $('form').serialize();
//Enviar por post
$.post('<% =Url.Action("SaveCustomer") %>', data, insertCallback);
}
function insertCallback(data)
{
alert(data);
}
</script>
Pues sí, así de simple resultó pasar el formulario al controlador y que este recibiera como parámetro el modelo asociado a la vista. Esta instrucción resume todo lo que necesitamos:
var data = $('form').serialize();
Pero, ¿dónde está el truco?
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 ID Name corresponde con el nombre de la propiedad que, al ser serializado, crea un JSON que hace corresponder ID=valor una representación en el formato clásico de URL (param=valor&m2=valor2&...).
Formulario serializado:
FirstName=aa&LastName=bb&UserName=aa.bb&Password=123&ConfirmPassword=123
Una curiosidad a tener en cuenta es: si miran el formulario podrán ver que he dejado fuera del formulario la propiedad Language de mi modelo, esto lo he hecho con toda intensió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í es necesario que cada ID Name de los elementos del formulario se corresponda con una propiedad llamada exactamente igual a la existente en el modelo.
Con esto… ya tenemos un post por ajax al controlador que recibe como parámetro el modelo asociado a la vista. Esto es posible también hacerlo usando ASP.NET, pero eso lo dejo para un próximo artículo.
;)
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.
Hay una regla de oro cuando trabajamos WinForm e hilos: Con el UI solo se interactúa desde el hilo principal de la aplicación.
Ayer publiqué un artículo sobre un trabajo que vengo haciendo para conectar un servicio y un cliente Silverlight usando Socket. Los sockets usan comunicación asincrónica por lo que el evento de lectura de datos sobre el puerto ocurre en hilos secundarios que son creados por la conexión para notificar a mi aplicación que tenemos información nueva que tratar.
Código que inicializa y conecta el sockets en Silverlight:
DnsEndPoint endPoint = new DnsEndPoint(
Application.Current.Host.Source.DnsSafeHost, 4530);
Socket socket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
args.UserToken = socket;
args.RemoteEndPoint = endPoint;
args.Completed += new EventHandler<SocketAsyncEventArgs>(OnSocketConnectCompleted);
socket.ConnectAsync(args);
Aquí podemos ver sin problemas la llamada al método ConnectAsync y la asignación del evento Completed que será lanzado por el socket en el momento en que la conexión o la lectura de datos sean completadas.
La información que me llega desde el servidor es transformada en objetos que son pintados dinámicamente en mi aplicación Silverlight. Esta operación es realizada en el método InitializeExtensionList:
private void OnSocketReceive(object sender, SocketAsyncEventArgs e)
{
var data = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred);
//Get initial team data
if (_extensions == null)
{
InitializeExtensionList(data);
}
//Prepare to receive more data
Socket socket = (Socket)e.UserToken;
socket.ReceiveAsync(e);
}
Pues bien, al intentar ejecutar mi aplicación me encuentro con el siguiente mensaje:

Ummm… Invalid Cross Thread Access: La excepción es UnauthorizedAccessException. El mensaje de error habla por sí solo. Se ha denegado el acceso al UI desde un hilo que no es el principal dentro de mi aplicación.
En aplicaciones Windows esto se resolvía mediante un delegado que me permitiera sincronizar el acceso al UI con el hilo principal de la aplicación.
Ejemplo en Windows Form:
EventHandler m_progress = delegate
{
_frmProgress.ShowQuality(userData.ToString());
};
Invoke(m_progress);
El código dentro del delegado interactúa con el UI, la sincronización con el hilo principal se realiza mediante el método Invoque.
Pero… ¿Cómo Silverlight me permitirá hacer esto?
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ó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.)
Esta clase tiene un método llamado BeginInvoke el cual recibe como parámetros un delegado y una matriz de valores que se pasan como argumentos (opcional).
Pues nada, que la historia de sincronización entre hilos secundarios y el hilo principal de la interfaz de usuario que tan común es en Windows Form, sobre todo cuando trabajamos con SmartClient, se repite en Silverlight. ;)
La forma correcta para ejecutar mi código sería:
private void OnSocketReceive(object sender, SocketAsyncEventArgs e)
{
var data = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred);
//Get initial team data
if (_extensions == null)
{
Dispatcher.BeginInvoke(() => InitializeExtensionList(data));
}
//Prepare to receive more data
Socket socket = (Socket)e.UserToken;
socket.ReceiveAsync(e);
}
Seguimos ;)
Hace tiempo que vengo intentando cubrir algunos huecos en mi formación sobre .NET que por falta de tiempo se me había hecho imposible llevar adelante. Se trata de Silverlight y WPF. Ahora y por cuestiones de trabajo, me ha tocado hacer frente a estos “baches”.
Como soy programador y no diseñador, paso un poco de toda esta tecnología en la que las posibilidades de crear User Interface (UI) ricas en animaciones o efectos visuales cobra mayor importancia. Así, enfrentar este nuevo reto me lleva por encontrar desde el punto de vista de análisis y desarrollo, las posibilidades que estas nuevas tecnologías traen asociadas.
Uno de los principales problemas cuando desarrollamos en Web, es la posibilidad de una comunicación asincrónica entre cliente y servidor. Con esto me refiero a la posibilidad de que la comunicación fluya en ambos sentidos y no tenga que ser el cliente (Aplicación WEB) quien realice constantemente las peticiones al servidor.
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ática anterior y conociendo las ventajas de esta nueva forma de desarrollo, me planteo para mi propio estudio la utilización de sockets dentro de SilverLight para realizar una conexión en la que el servidor sea quien se mantenga brindando continua información al cliente.
Esquema de desarrollo:

El esquema lo que muestra es una aplicación que desde un servidor interactúa con una pizarra telefónica (PBX) mediante TAPI y envía hacia un cliente WEB desarrollado con Silverlight el estado actual de cada una de las extensiones conectadas a la PBX. Para el artículo, solo nos concentraremos en la comunicación por socket entre el cliente Web y el servidor. He dibujado el diagrama completo para que vean las líneas que representan el sentido en que fluye la información en toda la aplicación. (Desde el servidor hacia el cliente)
Empezamos desarrollando una aplicación de consola con un socket server como normalmente lo hemos visto siempre en cualquier aplicación Windows. Este socket server estará a la escucha mediante un determinado puerto de cualquier petición de conexión realizada desde un cliente Web.
El TcpListener: Voy a pasar por alto la implementación detallada del servidor ya que no es el objetivo del artículo.
//create our TCPListener object
_sockServer = new System.Net.Sockets.TcpListener(IPAddress.Any, 4530);
Console.WriteLine("Started server...");
try
{
//start the chat server
_sockServer.Start();
while (true)
{
_tcpClientConnected.Reset();
Console.WriteLine("Waiting for client connection...");
_sockServer.BeginAcceptTcpClient(new AsyncCallback(OnBeginAccept), null);
_tcpClientConnected.WaitOne(); //Block until client connects
}
}
catch (Exception ex)
{
Console.Write(ex.ToString());
}
… OnBeginAccept
var _client = _sockServer.EndAcceptTcpClient(result);
InitializeExtensionList(_extensions);
_tcpClientConnected.Set(); //Allow waiting thread to proceed
Con este código inicializamos nuestro servidor y lo mantenemos a la escucha sobre el puerto 4530 de cualquier petición de conexión. En el momento en que una conexión es solicitada, se inicializa el listado de extensiones que no es más que enviar al cliente la información de todas las extensiones conectadas a la PBX.
La primera observación es el puerto seleccionado. Esto no es un antojo, nuestro cliente será una aplicació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ón desde una aplicación desarrollada en Silverlight a un puerto fuera de este rango, será denegado automáticamente.
Segunda observación es que usamos TCP como protocolo de comunicación, esto es lo normal cuando trabajamos con sockets aunque no está de más indicar que es el único protocolo permitido por Silverlight.
Lanzamos nuestro server para asegurarnos que todo marcha bien…

Todo bien… así que seguimos con lo que realmente importa, la aplicación cliente.
MainPage.xaml.cs : No voy a entrar en detalles de diseño o implementación del socket para no hacer extenso el artículo.
public MainPage()
{
InitializeComponent();
this.Loaded += Page_Loaded;
}
En el constructor de mi UserControl me subscribo al evento Loaded en el cual conectaré al servidor y esperaré como respuesta el listado de extensiones.
void Page_Loaded(object sender, RoutedEventArgs e)
{
var endPoint = new DnsEndPoint(Application.Current.Host.Source.DnsSafeHost, 4530);
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
args.UserToken = socket;
args.RemoteEndPoint = endPoint;
args.Completed += new EventHandler<SocketAsyncEventArgs>(OnSocketConnectCompleted);
socket.ConnectAsync(args);
}
Aquí vamos… Explicación rapidita: Este código identifica en primer lugar el servidor de la aplicación e inicializa un EndPoint mediante el puerto 4530 (Recuerden que Silverlight só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és de otros mé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ón. Una vez que estos objetos son creados y están listos para su uso, El método ConnectAsync del objeto Socket puede ser llamado indicando como argumento el SocketAsyncEventArgs.
private void OnSocketConnectCompleted(object sender, SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
… Success Connection
}
else
{
Dispatcher.BeginInvoke(() =>
System.Windows.Browser.HtmlPage.Window.Alert(e.SocketError.ToString()));
}
…
}
Con este código ya listo, lanzo mi aplicación cliente:

¡¡¡BOOM!!! ¿Acceso denegado? Y yo aprendiendo Silverlight, menudo problema. Mis primeros intentos de solución son los tan “mal” acostumbrados “prueba y error”. Sin tener muy claro qué estaba pasando empecé a intentar adivinar.
- Ya sé… el Firewall de Windows. Fuera Firewall pero el error seguía - Umm.. ya sé… el servidor no está funcionando bien. Hice una pequeña aplicación de consola que conectara al servidor y… ¡¡¡funcionó bien!!!
Cansado de tanto estira y encoje hice lo que debía hacer desde el principio. ¡Leer más!
Resulta que nuestro nuevo amiguito Silverlight establece unas políticas de seguridad, muy acertadas a mi criterio, en las que no permite conexión alguna si antes el servidor no valida que realmente se tenga acceso a este recurso.
El MSDN dice:
“Silverlight 2 y las versiones posteriores son compatibles con la conectividad entre dominios, lo que permite a una aplicación obtener acceso a recursos situados en ubicaciones que no son el sitio de origen. Se trata de una característica importante para que las aplicaciones de Silverlight puedan utilizar los servicios existentes en la Web.
El sistema de directivas de seguridad del motor en tiempo de ejecución de Silverlight requiere que se descargue un archivo de directivas desde un dominio de destino antes de permitir que una conexió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.”
¿Qué archivo es este y qué contiene? ¿Dónde pongo este archivo?
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:
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from>
<domain uri="*" />
</allow-from>
<grant-to>
<socket-resource port="4530" protocol="tcp" />
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
Relajitos con mi servidor ¡NO! ;)
Mediante este archivo nosotros le indicamos a cualquier cliente que intente conectar a nuestro recurso de red, que solo tendrá permiso si la petición se realiza desde un dominio que esté validado por nosotros (En este caso, vía libre a todo el mundo) y el recurso al que esté intentando conectar sea sí y solo sí, el puerto 4530. Muy bien aquí por Microsoft ;)
Ahora bien… ¿dónde pongo este archivo? De nuevo MSDN:
“En Silverlight versión 3, en el caso de una solicitud de conexión mediante System.Net.Sockets al sitio (entre dominios o sitio de origen), el runtime de Silverlight intenta abrir una conexión utilizando TCP a un puerto conocido (el puerto 943) en el sitio de destino. Si se puede establecer una conexión TCP, el runtime de Silverlight envía la cadena especial
al servidor para solicitar un archivo de directivas de sockets de Silverlight.
El motor en tiempo de ejecución de Silverlight, a continuació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á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ón completa de la aplicación de Silverlight.”
Esto significa que para probar mis aplicaciones en Silverlight, de algún modo necesito tener un servidor escuchando peticiones por el puerto 943 y, en caso de que se produzca una conexión, validamos que se trate de un cliente solicitando un archivo de directiva de seguridad para retornarle el XML.
Esto sería un problema si pensamos hostear servicios en servidores que no sean dedicados, por eso, para el caso de Silverlight 4, la petició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 él.
Para pruebas o cuando ejecutamos la aplicación dentro de Visual Studio, no podríamos publicar el XML por el puerto 80 ya que nuestra aplicación se ejecuta dentro del servidor web que trae el propio Visual Studio.
Para poder probar mis aplicaciones sin problemas me cree un pequeño Socket server que valida y retorna el archivo de directivas de seguridad solicitado por Silverlight.
class PolicySocketServer
{
private TcpListener _listener = null;
private TcpClient _client = null;
private static ManualResetEvent _tcpClientConnected = new ManualResetEvent(false);
private const string _policyRequestString = "<policy-file-request/>";
private int _receivedLength = 0;
private byte[] _policy = null;
private byte[] _receiveBuffer = null;
private void ReadXmlPolicyData()
{
string policyFile = ConfigurationManager.AppSettings["PolicyFilePath"];
using (FileStream fs = new FileStream(policyFile, FileMode.Open))
{
_policy = new byte[fs.Length];
fs.Read(_policy, 0, _policy.Length);
}
_receiveBuffer = new byte[_policyRequestString.Length];
}
public void StartSocketServer()
{
ReadXmlPolicyData();
_listener = new TcpListener(IPAddress.Any, 943);
_listener.Start();
Console.WriteLine("Policy server listening...");
while (true)
{
_tcpClientConnected.Reset();
Console.WriteLine("Waiting for client connection...");
_listener.BeginAcceptTcpClient(new AsyncCallback(OnBeginAccept), null);
_tcpClientConnected.WaitOne();
}
}
private void OnBeginAccept(IAsyncResult result)
{
_client = _listener.EndAcceptTcpClient(result);
_client.Client.BeginReceive(
_receiveBuffer, 0, _policyRequestString.Length, SocketFlags.None,
new AsyncCallback(OnReceiveComplete), null);
}
private void OnReceiveComplete(IAsyncResult result)
{
try
{
_receivedLength += _client.Client.EndReceive(result);
if (_receivedLength < _policyRequestString.Length)
{
_client.Client.BeginReceive(
_receiveBuffer,
_receivedLength,
_policyRequestString.Length - _receivedLength,
SocketFlags.None,
new AsyncCallback(OnReceiveComplete), null);
return;
}
//Check <policy-file-request/>
string request = System.Text.Encoding.UTF8.GetString(
_receiveBuffer,
0,
_receivedLength);
if (StringComparer.InvariantCultureIgnoreCase.Compare(request, _policyRequestString) != 0)
{
//Isn't valid... bye bye
_client.Client.Close();
return;
}
//Is Okay....send policy file
_client.Client.BeginSend(
_policy,
0,
_policy.Length,
SocketFlags.None,
new AsyncCallback(OnSendComplete),
null);
}
catch (Exception ex)
{
_client.Client.Close();
Console.Write(ex.ToString());
}
_receivedLength = 0;
_tcpClientConnected.Set(); //Allow waiting thread to proceed
}
private void OnSendComplete(IAsyncResult result)
{
tr
{
_client.Client.EndSendFile(result);
}
catch (Exception ex)
{
Console.Write(ex.ToString());
}
finally
{
_client.Client.Close();
}
}
}
Era mi primer evento online. Nunca había dado una clase o evento sin poder ver las caras de las personas que me escuchan. En principio pensé que esto sería malo, pero ya creo que también tiene su parte buena.
Lo malo, no podré saber si están entendiendo o no lo que les estoy contando Lo bueno, no podré saber si tienen esa cara que se les queda a todo el mundo cuando se pregunta, “que tontería está hablando este” ;)
Ya parejos, F5:
Encuesta: Con el objetivo de conocer la opinión de los presentes sobre programar o pensar orientado a objetos, se realizó la siguiente encuesta.
1- ¿Programamos orientado a objetos?
2- Cuando programamos, ¿Pensamos orientado a objetos?
Presentación
En este evento pretendíamos repasar de forma muy elemental los principales conceptos sobre programación orientada a objetos. La mayoría de los lenguajes de programación son hoy en día orientados a objetos. Esto puede traernos confusión al pensar que por programar sobre un lenguaje que sea orientado a objetos, estamos programando orientado a objetos.
Un posible ejemplo de esta confusión es el desarrollo de aplicaciones ASPNET y el Desarrollo en Capas. Podemos crear un proyecto ASPNET donde todo el código esté en un mismo proyecto, donde las consultas se realicen escribiendo directamente el SQL en el code behind y nuestro programa funcionaría, pero ¿Es correcto? NO
Un poco de historia
¿Cómo surge todo esto de la programación orientada a objetos y dónde radica su verdadera importancia?
Todo empezó en la llamada “crisis del software” entre los años 60 y 70.
¿En qué consistía esta crisis?

Los "grandes" grupos de programadores que programaban los "grandes" sistemas para los "grandes” ordenadores tenían serios problemas de organización y productividad. Pocos sistemas lograban terminarse, en pocos se terminaban cumpliendo los requerimientos iniciales y no todos los que se terminaban cumpliéndolos, se usaban según lo planificado.
El problema, que en aquel entonces se llamó de forma incorrecta de “mantenimiento”, consistía en cómo adaptar el software a nuevos requerimientos imposibles de haber sido planificados inicialmente.
La planificación y previsión es contrario a la propia realidad.
Nosotros, las personas, aprendemos y creamos a través de la experimentación, no de la planificación. Si no hay experiencia, no aprendemos, y la experiencia solo llega experimentando y no planificando.
Soy un niño y quiero correr (Experimentar) me caí y me di un golpe (Experiencia) ya sé que no puedo correr sino que debo caminar (enseñanza)
Es imposible y eso creo que todos los sabemos, que exista un proyecto que pueda ser planificado por entero antes de escribir una línea de código, y mucho más imposible, convertir la planificación en una camisa de fuerza en el desarrollo y evolución del sistema.
Aún en la actualidad, se lucha por crear planificaciones adaptables. Las Metodologías ágiles, por ejemplo, intentan planificar un proyecto de software adaptándolo constantemente a los cambios que surgen durante su etapa de desarrollo.
¿Por qué toda esta historia?
¿Es la POO un mejor paradigma que otros? En cierto sentido sí lo es. ¿Es una cura de todos nuestros problemas? No, no lo es. ¿Significa que "crisis del software" desaparecerá? Probablemente no. Y entonces se preguntarán, ¿qué es lo grande de la Programación Orientada a Objetos?
Acercar el ordenador al problema y no al revés. 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
Principales pilares de la programación orientada a objetos.

Encapsulamiento:
Es importante limitar correctamente el acceso a un objeto. Un objeto es un elemento que contiene propiedades y que realiza acciones.
Un avión tiene ruedas, un color, puertas, halas alas. Además realiza acciones como despegar, aterrizar, planear, girar a un sentido u otro. Sobre el avión se realizan acciones que cambian su comportamiento y este, modifica el estado.
Supongamos que el avión contiene un estado que nos indica si está en tierra o en el aire. Jamás deberíamos poder modificar ese estado si no es mediante una acción.
- Estado (En tierra)
- Acción (Despegar). Si despegar fue correcto, cambiar estado (en el aire)
- Estado (En el aire)
Herencia:
Hay que procrear, procreen mucho y así damos continuidad a nuestra especie. Pero, cuidado, no se puede ir haciendo hijos por ahí si no estamos seguros de que le vamos a transmitir y que van a usar todo lo que sabemos.
Esto es herencia. Necesitamos hijos que se apoyen de nuestra experiencia y la apliquen en forma de enseñanza. Lo sé, porque mi padre me lo dijo y listo. Cómo lo supo el padre no importa, eso queda en el encapsulamiento ;)
Piensen en el ejemplo del niño que corre. Los padres constantemente intentan transmitir cuidado, enseñanzas de que no se debe correr para evitar un golpe. El niño no se preocupa cómo sus padres lo aprendieron, “casi siempre” obedecen.
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ían dos personas totalmente distintas. Dos objetos distintos.
La herencia, entre otras cosas, es para un informático el pan nuestro de cada día. Reutilización, no escriban lo mismo dos veces. 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.
Cohesión/ Especialización (ver comentarios al final del artículo):
Esto es la especialización de cada objeto. Tenemos que llegar a lograr que cada objeto se especialice solo en lo que sabe hacer, extendernos haría que termináramos mezclando funcionalidad.
La silla, fue diseñada solo para sentarnos. Algunos la usamos como escalera, pero no fue diseñado para eso. Cuando usamos la silla como escalera y nos caemos decimos: claro, era una silla y no una escalera.
El perro es un perro y el gato es un gato, no hay un perro-gato. Un coche es un coche y un avión es un avión. Y si no me creen, intenten volar con un coche.
Los objetos mientras mayor sea su cohesión, mejor podremos definir su comportamiento.
Abstracción:
Aquí pensamos en qué hace y no en cómo lo hace. Dentro de la programación orientada a objeto la Abstracción nos permite definir características del objeto, modelar su comportamiento sin llegar a especificar el cómo lo hace.
En la realidad, el ser humano no piensa en las cosas como un conjunto de pequeñas cosas sino que las entendemos como objetos con comportamientos bien definidos.
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ómo nuestro deseo llegó al cerebro y este envía el mensaje en forma de acción hacia los músculos de los pies para provocar el movimiento. Simplemente, caminamos y eso define el comportamiento.
El principio de abstracción es precisamente esto: Lograr tener objetos con comportamientos bien definidos e irlos dividiendo sucesivamente en conjuntos de subsistemas cada vez más especializados.
El objeto animal es un ejemplo de abstracción, tiene características como edad, sexo, color y realiza acciones como comer, dormir o desplazarse. La especialización de esta abstracción podría ser un objeto perro, gato, paloma o persona, cada nuevo objeto implementa el cómo hará cada acción.
Polimorfismo:
Es la capacidad que permite mantener organizada varias acciones en objetos heredados que aun significando lo mismo, se realizan de manera diferente.
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ón a realizar es Despegar, pero la manera en que lo hacen es diferente.
En POO, el polimorfismo se aplica cuando necesitamos sobre escribir métodos o atributos llamados de forma idéntica pero con un comportamiento distinto.
No confundir polimorfismo con sobre-carga: Polimorfismo (Entre clases, se resuelve en tiempo de ejecución) Sobre-carga (métodos de la misma clase, se resuelve en tiempo de compilación)
Acoplamiento:
Es la dependencia existente entre objetos para poder funcionar.
La comunicación entre objetos siempre se realiza mediante acciones (llamadas a métodos) y es conocida como comunicación por mensajes. Haz esto, hora tú haz aquello para yo luego poder hacer lo mío.
Si bien es verdad que mientras menos acoplamiento exista entre los objetos, mejor encapsulado quedará el objeto, debemos tener mucho cuidado en no mezclar responsabilidades.
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í misma. A la tuerca, se le hace rosca, que es quien permite el ajuste y por fuera se le da diferentes formas segú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.
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.
PD: Este artículo continuará con la explicación de los ejemplos utilizados en el evento. De todas formas, pueden descargarse toda la documentación y ver el evento desde la página del grupo de usuarios SNUG
Salu2
Bibliografía utilizada: Programación Orientada a Objetos en C++ - Miguel Katrib Mora.
Aquí les dejo un tips de WinForm tan rápido como me lo permite el tiempo.
Problemática: Necesitamos crear archivos desde nuestra aplicación que sean modificados por todos los usuarios del sistema operativo sin importar los permisos otorgados. Microsoft aconseja que cuando necesitemos guardar este tipo de información, usemos el CommonApplicationData, el cual es accesible para todos los usuarios.
Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)
La estructura organizativa que se aconseja mantener en dicho directorio sería [Nombre de la compañía\Nombre de la aplicación], pero esto incluye una problemática a nuestro desarrollo, y es que a los archivos creados desde nuestra aplicación, se les asignan permisos de escritura restringidos solo a su creador (El usuario que ejecuta la aplicació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án limitados solamente al grupo [Todos los usuarios], se nos denegará el acceso a modificar los archivos creados por el usuario anterior.
Resolución: Al crear la carpeta que contendrá nuestros archivos para la aplicación, asigné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.
Aquí les dejo una pequeña clase que permite crear carpetas desde nuestra aplicación indicando si deseamos asignar acceso total a todos los usuarios.
public class CommonApplicationData
{
public static void CreateFolder(string folderName, bool allUsers)
{
if (Directory.Exists(folderName)) return;
var m_securityIdentifier =
new SecurityIdentifier(WellKnownSidType.WorldSid, null);
var m_directoryInfo = Directory.CreateDirectory(folderName);
if (!allUsers) return;
bool m_modified;
var m_directorySecurity = m_directoryInfo.GetAccessControl();
AccessRule m_rule =
new FileSystemAccessRule(m_securityIdentifier,
FileSystemRights.FullControl,
InheritanceFlags.ContainerInherit |
InheritanceFlags.ObjectInherit,
PropagationFlags.InheritOnly,
AccessControlType.Allow);
m_directorySecurity.
ModifyAccessRule(AccessControlModification.Add,
m_rule, out m_modified);
m_directoryInfo.SetAccessControl(m_directorySecurity);
}
}
Salu2
Más artículos
Página siguiente >