changeset 140:3639803112c6

Refactoring de la relación entre Evento y Estado
author nelopauselli
date Fri, 29 Jul 2011 16:30:53 -0300
parents 18e5a78186e4
children a5ff4de4a1d3
files Agendas/trunk/src/Agendas.Domain/Evento.cs Agendas/trunk/src/Agendas.Domain/EventoAgendadoState.cs Agendas/trunk/src/Agendas.Domain/EventoCanceladoState.cs Agendas/trunk/src/Agendas.Domain/EventoConfirmadoState.cs Agendas/trunk/src/Agendas.Domain/EventoDescartadoState.cs Agendas/trunk/src/Agendas.Domain/EventoNullState.cs Agendas/trunk/src/Agendas.Domain/EventoPropuestoState.cs Agendas/trunk/src/Agendas.Domain/EventoPublicadoState.cs Agendas/trunk/src/Agendas.Domain/EventoState.cs Agendas/trunk/src/Agendas.NHibernate/Agendas.NHibernate.csproj Agendas/trunk/src/Agendas.NHibernate/EventoStateType.cs Agendas/trunk/src/Agendas.NHibernate/GenericWellKnownInstanceType.cs Agendas/trunk/src/Agendas.NHibernate/NhHelper.cs Agendas/trunk/src/Agendas.Repositories.Memory/EventoRepository.cs Agendas/trunk/src/Agendas.Repositories.NHibernate/EventoRepository.cs Agendas/trunk/src/Agendas.Tests/AgendarTests.cs Agendas/trunk/src/Agendas.Tests/Agendas.Tests.csproj Agendas/trunk/src/Agendas.Tests/Cruds/EventoCrud.cs Agendas/trunk/src/Agendas.Tests/Cruds/EventoCrudMemoryTests.cs Agendas/trunk/src/Agendas.Tests/Cruds/EventoCrudNhTests.cs Agendas/trunk/src/Agendas.Tests/EventoStateTests.cs Agendas/trunk/src/Agendas.Web/Controllers/EventoController.cs
diffstat 22 files changed, 484 insertions(+), 317 deletions(-) [+]
line wrap: on
line diff
--- a/Agendas/trunk/src/Agendas.Domain/Evento.cs	Thu Jul 28 10:16:09 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Domain/Evento.cs	Fri Jul 29 16:30:53 2011 -0300
@@ -1,7 +1,5 @@
 using System;
-using System.Collections;
 using System.Collections.Generic;
-using AltNetHispano.Agendas.Domain.Exceptions;
 
 namespace AltNetHispano.Agendas.Domain
 {
@@ -56,63 +54,20 @@
 			get { return _tracks; }
 		}
 
+		private EventoState _estado;
+
 		/// <summary>
 		/// Estado del evento en formato string (para persistencia a DB)
 		/// </summary>
-		public virtual string Estado
+		public virtual EventoState Estado
 		{
-			get
-			{
-				if (_eventoState != null)
-					return _eventoState.GetDescripcion();
-
-				return string.Empty;
-			}
-			set
-			{
-				if (value != Estado)
-				{
-					if (EventoPropuestoState.GetInstance().GetDescripcion().Equals(value))
-						_eventoState = EventoPropuestoState.GetInstance();
-					else if (EventoAgendadoState.GetInstance().GetDescripcion().Equals(value))
-						_eventoState = EventoAgendadoState.GetInstance();
-					else if (EventoConfirmadoState.GetInstance().GetDescripcion().Equals(value))
-						_eventoState = EventoConfirmadoState.GetInstance();
-					else if (EventoPublicadoState.GetInstance().GetDescripcion().Equals(value))
-						_eventoState = EventoPublicadoState.GetInstance();
-					else if (EventoCanceladoState.GetInstance().GetDescripcion().Equals(value))
-						_eventoState = EventoCanceladoState.GetInstance();
-					else if (EventoDescartadoState.GetInstance().GetDescripcion().Equals(value))
-						_eventoState = EventoDescartadoState.GetInstance();
-					else
-						throw new InvalidStateException(value);
-				}
-			}
+			get { return _estado ?? EventoNullState.GetInstance(); }
+			set { _estado = value; }
 		}
 
-		private EventoState _eventoState;
+		//private EventoState _eventoState;
 		private IList<Patrocinador> _patrocinadores;
 
-		/// <summary>
-		/// Obtiene una instancia de la clase que representa el estado del evento
-		/// </summary>
-		public virtual EventoState GetEstado()
-		{
-			if (_eventoState == null)
-				SetEstado(EventoNullState.GetInstance());
-
-			return _eventoState;
-		}
-
-		/// <summary>
-		/// Asigna la instancia de la clase que representa el estado del evento
-		/// </summary>
-		/// <param name="eventoState">Instancia que representa el estado</param>
-		public virtual void SetEstado(EventoState eventoState)
-		{
-			_eventoState = eventoState;
-		}
-
 		public virtual TipoEvento Tipo { get; private set; }
 
 		public virtual IEnumerable<Patrocinador> Patrocinadores
@@ -149,7 +104,7 @@
 		public static Evento Proponer(string titulo, Persona persona, string urlInvitacion, TipoEvento tipo)
 		{
 			var evento = new Evento { Titulo = titulo, Ponente = persona, UrlInvitacion = urlInvitacion, Tipo = tipo };
-			evento.GetEstado().Promover(evento, Accion.Proponer);
+			evento.Estado.Promover(evento, Accion.Proponer);
 
 			return evento;
 		}
@@ -182,7 +137,7 @@
 			Ponente = persona;
 			Fecha = fecha;
 			UrlInvitacion = urlInvitacion;
-			this.GetEstado().Promover(this, Accion.Agendar);
+			this.Estado.Promover(this, Accion.Agendar);
 		}
 
 		public virtual void Actualizar(Persona persona, DateTime? fecha, string urlInvitacion)
@@ -202,34 +157,34 @@
 
 		public virtual void Confirmar()
 		{
-			this.GetEstado().Promover(this, Accion.Confirmar);
+			this.Estado.Promover(this, Accion.Confirmar);
 		}
 
 		public virtual void Publicar(short numeroOrden, string urlWiki)
 		{
 			this.NumeroOrden = numeroOrden;
 			this.UrlWiki = urlWiki;
-			this.GetEstado().Promover(this, Accion.Publicar);
+			this.Estado.Promover(this, Accion.Publicar);
 		}
 
 		public virtual void Cancelar()
 		{
-			GetEstado().Promover(this, Accion.Cancelar);
+			Estado.Promover(this, Accion.Cancelar);
 		}
 
 		public virtual void Descartar()
 		{
-			GetEstado().Promover(this, Accion.Descartar);
+			Estado.Promover(this, Accion.Descartar);
 		}
 
 		public virtual void ReProponer()
 		{
-			GetEstado().Promover(this, Accion.ReProponer);
+			Estado.Promover(this, Accion.ReProponer);
 		}
 
 		public virtual void ReAgendar()
 		{
-			GetEstado().Promover(this, Accion.ReAgendar);
+			Estado.Promover(this, Accion.ReAgendar);
 		}
 		#endregion
 
--- a/Agendas/trunk/src/Agendas.Domain/EventoAgendadoState.cs	Thu Jul 28 10:16:09 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Domain/EventoAgendadoState.cs	Fri Jul 29 16:30:53 2011 -0300
@@ -1,47 +1,44 @@
-using System;
-using AltNetHispano.Agendas.Domain.Exceptions;
+using AltNetHispano.Agendas.Domain.Exceptions;
 
 namespace AltNetHispano.Agendas.Domain
 {
-  public class EventoAgendadoState : EventoState
-  {
-    private EventoAgendadoState()
-    {
-    }
+	public class EventoAgendadoState : EventoState
+	{
+		protected EventoAgendadoState()
+		{
+		}
 
-    private static readonly EventoState _instance = new EventoAgendadoState();
-    public static EventoState GetInstance()
-    {
-      return _instance;
-    }
-
-    private const string Descripcion = "Agendado";
+		private static readonly EventoState _instance = new EventoAgendadoState();
+		public static EventoState GetInstance()
+		{
+			return _instance;
+		}
 
-    public override void Promover(Evento evento, Accion accion)
-    {
-        switch (accion)
-        {
-            case Accion.Confirmar:
-                evento.SetEstado(EventoConfirmadoState.GetInstance());
-                evento.AddTrack(new Track(evento, Accion.Confirmar));
-                break;
-            case Accion.Cancelar:
-                evento.SetEstado(EventoCanceladoState.GetInstance());
-                evento.AddTrack(new Track(evento, Accion.Cancelar));
-                break;
-            default:
-                throw new AccionNoSoportadaException(this.GetType(), accion);
-        }
-    }
+		public override void Promover(Evento evento, Accion accion)
+		{
+			switch (accion)
+			{
+				case Accion.Confirmar:
+					evento.Estado=EventoConfirmadoState.GetInstance();
+					evento.AddTrack(new Track(evento, Accion.Confirmar));
+					break;
+				case Accion.Cancelar:
+					evento.Estado = EventoCanceladoState.GetInstance();
+					evento.AddTrack(new Track(evento, Accion.Cancelar));
+					break;
+				default:
+					throw new AccionNoSoportadaException(this.GetType(), accion);
+			}
+		}
 
-    public override string GetDescripcion()
-    {
-      return Descripcion;
-    }
+		public override string Descripcion
+		{
+			get { return "Agendado"; }
+		}
 
-  	public override bool PuedePromover(Accion accion)
-  	{
-		return accion == Accion.Confirmar || accion == Accion.Cancelar;
-  	}
-  }
+		public override bool PuedePromover(Accion accion)
+		{
+			return accion == Accion.Confirmar || accion == Accion.Cancelar;
+		}
+	}
 }
\ No newline at end of file
--- a/Agendas/trunk/src/Agendas.Domain/EventoCanceladoState.cs	Thu Jul 28 10:16:09 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Domain/EventoCanceladoState.cs	Fri Jul 29 16:30:53 2011 -0300
@@ -1,51 +1,50 @@
-using AltNetHispano.Agendas.Domain.Exceptions;
+using System;
+using AltNetHispano.Agendas.Domain.Exceptions;
 
 namespace AltNetHispano.Agendas.Domain
 {
-    public class EventoCanceladoState : EventoState
-    {
-        private EventoCanceladoState()
-        {
-        }
+	public class EventoCanceladoState : EventoState
+	{
+		protected EventoCanceladoState()
+		{
+		}
 
-        private static readonly EventoState _instance = new EventoCanceladoState();
+		private static readonly EventoState _instance = new EventoCanceladoState();
 
-        public static EventoState GetInstance()
-        {
-            return _instance;
-        }
-
-        private const string Descripcion = "Cancelado";
+		public static EventoState GetInstance()
+		{
+			return _instance;
+		}
 
-        public override void Promover(Evento evento, Accion accion)
-        {
-            switch (accion)
-            {
-                case Accion.Descartar:
-                    evento.SetEstado(EventoDescartadoState.GetInstance());
-                    evento.AddTrack(new Track(evento, Accion.Descartar));
-                    break;
-                case Accion.ReAgendar:
-                    evento.SetEstado(EventoAgendadoState.GetInstance());
-                    evento.AddTrack(new Track(evento, Accion.ReAgendar));
-                    break;
-                case Accion.ReProponer:
-                    evento.SetEstado(EventoPropuestoState.GetInstance());
-                    evento.AddTrack(new Track(evento, Accion.ReProponer));
-                    break;
-                default:
-                    throw new AccionNoSoportadaException(this.GetType(), accion);
-            }
-        }
+		public override void Promover(Evento evento, Accion accion)
+		{
+			switch (accion)
+			{
+				case Accion.Descartar:
+					evento.Estado = EventoDescartadoState.GetInstance();
+					evento.AddTrack(new Track(evento, Accion.Descartar));
+					break;
+				case Accion.ReAgendar:
+					evento.Estado = EventoAgendadoState.GetInstance();
+					evento.AddTrack(new Track(evento, Accion.ReAgendar));
+					break;
+				case Accion.ReProponer:
+					evento.Estado = EventoPropuestoState.GetInstance();
+					evento.AddTrack(new Track(evento, Accion.ReProponer));
+					break;
+				default:
+					throw new AccionNoSoportadaException(this.GetType(), accion);
+			}
+		}
 
-        public override string GetDescripcion()
-        {
-            return Descripcion;
-        }
+		public override string Descripcion
+		{
+			get { return "Cancelado"; }
+		}
 
-        public override bool PuedePromover(Accion accion)
-        {
-            return accion == Accion.Descartar || accion == Accion.ReAgendar || accion == Accion.ReProponer;
-        }
-    }
+		public override bool PuedePromover(Accion accion)
+		{
+			return accion == Accion.Descartar || accion == Accion.ReAgendar || accion == Accion.ReProponer;
+		}
+	}
 }
\ No newline at end of file
--- a/Agendas/trunk/src/Agendas.Domain/EventoConfirmadoState.cs	Thu Jul 28 10:16:09 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Domain/EventoConfirmadoState.cs	Fri Jul 29 16:30:53 2011 -0300
@@ -3,41 +3,39 @@
 
 namespace AltNetHispano.Agendas.Domain
 {
-  public class EventoConfirmadoState : EventoState
-  {
-    private EventoConfirmadoState()
-    {
-    }
+	public class EventoConfirmadoState : EventoState
+	{
+		protected EventoConfirmadoState()
+		{
+		}
 
-    private static readonly EventoState _instance = new EventoConfirmadoState();
-    public static EventoState GetInstance()
-    {
-      return _instance;
-    }
-
-    private const string Descripcion = "Confirmado";
+		private static readonly EventoState _instance = new EventoConfirmadoState();
+		public static EventoState GetInstance()
+		{
+			return _instance;
+		}
 
-    public override void Promover(Evento evento, Accion accion)
-    {
-      switch (accion)
-      {
-        case Accion.Publicar:
-          evento.SetEstado(EventoPublicadoState.GetInstance());
-          evento.AddTrack(new Track(evento, Accion.Publicar));
-          break;
-        default:
-          throw new AccionNoSoportadaException(this.GetType(), accion);
-      }
-    }
+		public override void Promover(Evento evento, Accion accion)
+		{
+			switch (accion)
+			{
+				case Accion.Publicar:
+					evento.Estado = EventoPublicadoState.GetInstance();
+					evento.AddTrack(new Track(evento, Accion.Publicar));
+					break;
+				default:
+					throw new AccionNoSoportadaException(this.GetType(), accion);
+			}
+		}
 
-    public override string GetDescripcion()
-    {
-      return Descripcion;
-    }
+		public override string Descripcion
+		{
+			get { return "Confirmado"; }
+		}
 
-  	public override bool PuedePromover(Accion accion)
-  	{
-  		return accion == Accion.Publicar;
-  	}
-  }
+		public override bool PuedePromover(Accion accion)
+		{
+			return accion == Accion.Publicar;
+		}
+	}
 }
\ No newline at end of file
--- a/Agendas/trunk/src/Agendas.Domain/EventoDescartadoState.cs	Thu Jul 28 10:16:09 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Domain/EventoDescartadoState.cs	Fri Jul 29 16:30:53 2011 -0300
@@ -1,10 +1,11 @@
-using AltNetHispano.Agendas.Domain.Exceptions;
+using System;
+using AltNetHispano.Agendas.Domain.Exceptions;
 
 namespace AltNetHispano.Agendas.Domain
 {
     public class EventoDescartadoState : EventoState
     {
-        private EventoDescartadoState()
+		protected EventoDescartadoState()
         {
         }
 
@@ -15,19 +16,17 @@
             return _instance;
         }
 
-        private const string Descripcion = "Descartado";
-
         public override void Promover(Evento evento, Accion accion)
         {
             throw new AccionNoSoportadaException(this.GetType(), accion);
         }
 
-        public override string GetDescripcion()
-        {
-            return Descripcion;
-        }
+    	public override string Descripcion
+    	{
+			get { return "Descartado"; }
+    	}
 
-        public override bool PuedePromover(Accion accion)
+    	public override bool PuedePromover(Accion accion)
         {
             return false;
         }
--- a/Agendas/trunk/src/Agendas.Domain/EventoNullState.cs	Thu Jul 28 10:16:09 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Domain/EventoNullState.cs	Fri Jul 29 16:30:53 2011 -0300
@@ -3,45 +3,43 @@
 
 namespace AltNetHispano.Agendas.Domain
 {
-  public class EventoNullState : EventoState
-  {
-    private EventoNullState()
-    {
-    }
+	public class EventoNullState : EventoState
+	{
+		protected EventoNullState()
+		{
+		}
 
-    private static readonly EventoState _instance = new EventoNullState();
-    public static EventoState GetInstance()
-    {
-      return _instance;
-    }
-
-    private const string Descripcion = "NullState";
+		private static readonly EventoState _instance = new EventoNullState();
+		public static EventoState GetInstance()
+		{
+			return _instance;
+		}
 
-    public override void Promover(Evento evento, Accion accion)
-    {
-      switch (accion)
-      {
-        case Accion.Proponer:
-          evento.SetEstado(EventoPropuestoState.GetInstance());
-          evento.AddTrack(new Track(evento, Accion.Proponer));
-          break;
-        case Accion.Agendar:
-          evento.SetEstado(EventoAgendadoState.GetInstance());
-          evento.AddTrack(new Track(evento, Accion.Agendar));
-          break;
-        default:
-          throw new AccionNoSoportadaException(this.GetType(), accion);
-      }
-    }
+		public override void Promover(Evento evento, Accion accion)
+		{
+			switch (accion)
+			{
+				case Accion.Proponer:
+					evento.Estado = EventoPropuestoState.GetInstance();
+					evento.AddTrack(new Track(evento, Accion.Proponer));
+					break;
+				case Accion.Agendar:
+					evento.Estado = EventoAgendadoState.GetInstance();
+					evento.AddTrack(new Track(evento, Accion.Agendar));
+					break;
+				default:
+					throw new AccionNoSoportadaException(this.GetType(), accion);
+			}
+		}
 
-    public override string GetDescripcion()
-    {
-      return Descripcion;
-    }
+		public override string Descripcion
+		{
+			get { return "NullState"; }
+		}
 
-  	public override bool PuedePromover(Accion accion)
-  	{
-  		return accion == Accion.Proponer || accion == Accion.Agendar;
-  	}
-  }
+		public override bool PuedePromover(Accion accion)
+		{
+			return accion == Accion.Proponer || accion == Accion.Agendar;
+		}
+	}
 }
\ No newline at end of file
--- a/Agendas/trunk/src/Agendas.Domain/EventoPropuestoState.cs	Thu Jul 28 10:16:09 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Domain/EventoPropuestoState.cs	Fri Jul 29 16:30:53 2011 -0300
@@ -3,45 +3,43 @@
 
 namespace AltNetHispano.Agendas.Domain
 {
-  public class EventoPropuestoState : EventoState
-  {
-    private EventoPropuestoState()
-    {
-    }
+	public class EventoPropuestoState : EventoState
+	{
+		protected EventoPropuestoState()
+		{
+		}
 
-    private static readonly EventoState _instance = new EventoPropuestoState();
-    public static EventoState GetInstance()
-    {
-      return _instance;
-    }
-
-    private const string Descripcion = "Propuesto";
+		private static readonly EventoState _instance = new EventoPropuestoState();
+		public static EventoState GetInstance()
+		{
+			return _instance;
+		}
 
-    public override void Promover(Evento evento, Accion accion)
-    {
-        switch (accion)
-        {
-            case Accion.Agendar:
-                evento.SetEstado(EventoAgendadoState.GetInstance());
-                evento.AddTrack(new Track(evento, Accion.Agendar));
-                break;
-            case Accion.Descartar:
-                evento.SetEstado(EventoDescartadoState.GetInstance());
-                evento.AddTrack(new Track(evento, Accion.Descartar));
-                break;
-            default:
-                throw new AccionNoSoportadaException(this.GetType(), accion);
-        }
-    }
+		public override void Promover(Evento evento, Accion accion)
+		{
+			switch (accion)
+			{
+				case Accion.Agendar:
+					evento.Estado = EventoAgendadoState.GetInstance();
+					evento.AddTrack(new Track(evento, Accion.Agendar));
+					break;
+				case Accion.Descartar:
+					evento.Estado = EventoDescartadoState.GetInstance();
+					evento.AddTrack(new Track(evento, Accion.Descartar));
+					break;
+				default:
+					throw new AccionNoSoportadaException(this.GetType(), accion);
+			}
+		}
 
-    public override string GetDescripcion()
-    {
-      return Descripcion;
-    }
+		public override string Descripcion
+		{
+			get { return "Propuesto"; }
+		}
 
-  	public override bool PuedePromover(Accion accion)
-  	{
-  		return accion == Accion.Agendar || accion == Accion.Descartar;
-  	}
-  }
+		public override bool PuedePromover(Accion accion)
+		{
+			return accion == Accion.Agendar || accion == Accion.Descartar;
+		}
+	}
 }
\ No newline at end of file
--- a/Agendas/trunk/src/Agendas.Domain/EventoPublicadoState.cs	Thu Jul 28 10:16:09 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Domain/EventoPublicadoState.cs	Fri Jul 29 16:30:53 2011 -0300
@@ -3,33 +3,31 @@
 
 namespace AltNetHispano.Agendas.Domain
 {
-  public class EventoPublicadoState : EventoState
-  {
-    private EventoPublicadoState()
-    {
-    }
+	public class EventoPublicadoState : EventoState
+	{
+		protected EventoPublicadoState()
+		{
+		}
 
-    private static readonly EventoState _instance = new EventoPublicadoState();
-    public static EventoState GetInstance()
-    {
-      return _instance;
-    }
-
-    private const string Descripcion = "Publicado";
+		private static readonly EventoState _instance = new EventoPublicadoState();
+		public static EventoState GetInstance()
+		{
+			return _instance;
+		}
 
-    public override void Promover(Evento evento, Accion accion)
-    {
-      throw new AccionNoSoportadaException(this.GetType(), accion);
-    }
+		public override void Promover(Evento evento, Accion accion)
+		{
+			throw new AccionNoSoportadaException(this.GetType(), accion);
+		}
 
-    public override string GetDescripcion()
-    {
-      return Descripcion;
-    }
+		public override string Descripcion
+		{
+			get { return "Publicado"; }
+		}
 
-  	public override bool PuedePromover(Accion accion)
-  	{
-  		return false;
-  	}
-  }
+		public override bool PuedePromover(Accion accion)
+		{
+			return false;
+		}
+	}
 }
\ No newline at end of file
--- a/Agendas/trunk/src/Agendas.Domain/EventoState.cs	Thu Jul 28 10:16:09 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Domain/EventoState.cs	Fri Jul 29 16:30:53 2011 -0300
@@ -1,16 +1,13 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+using System.Collections.Generic;
 
 namespace AltNetHispano.Agendas.Domain
 {
-  public abstract class EventoState
-  {
-    public abstract void Promover(Evento evento, Accion accion);
+	public abstract class EventoState
+	{
+		public abstract void Promover(Evento evento, Accion accion);
 
-    public abstract string GetDescripcion();
+		public abstract string Descripcion { get; }
 
-  	public abstract bool PuedePromover(Accion accion);
-  }
-}
+		public abstract bool PuedePromover(Accion accion);
+	}
+}
\ No newline at end of file
--- a/Agendas/trunk/src/Agendas.NHibernate/Agendas.NHibernate.csproj	Thu Jul 28 10:16:09 2011 -0300
+++ b/Agendas/trunk/src/Agendas.NHibernate/Agendas.NHibernate.csproj	Fri Jul 29 16:30:53 2011 -0300
@@ -53,6 +53,8 @@
     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="EventoStateType.cs" />
+    <Compile Include="GenericWellKnownInstanceType.cs" />
     <Compile Include="NhHelper.cs" />
     <Compile Include="NHibernateSessionPerActionAttribute.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Agendas/trunk/src/Agendas.NHibernate/EventoStateType.cs	Fri Jul 29 16:30:53 2011 -0300
@@ -0,0 +1,32 @@
+using System.Collections.Generic;
+using AltNetHispano.Agendas.Domain;
+using NHibernate.SqlTypes;
+
+namespace Agendas.NHibernate
+{
+	public class EventoStateType : GenericWellKnownInstanceType<EventoState, string> 
+	{
+		public static IEnumerable<EventoState> All
+		{
+			get
+			{
+				return new[]
+			       	{
+			       		EventoNullState.GetInstance(), EventoPropuestoState.GetInstance(), EventoAgendadoState.GetInstance(),
+			       		EventoConfirmadoState.GetInstance(), EventoPublicadoState.GetInstance(), EventoCanceladoState.GetInstance(),
+			       		EventoDescartadoState.GetInstance()
+			       	};
+			}
+		}
+
+		public EventoStateType()
+			: base(All, (state, id) => state.Descripcion == id, state => state.Descripcion)
+		{
+		}
+
+		public override SqlType[] SqlTypes
+		{
+			get { return new[] {SqlTypeFactory.GetString(25)}; }
+		}
+	}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Agendas/trunk/src/Agendas.NHibernate/GenericWellKnownInstanceType.cs	Fri Jul 29 16:30:53 2011 -0300
@@ -0,0 +1,114 @@
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq;
+using NHibernate.SqlTypes;
+using NHibernate.UserTypes;
+
+namespace Agendas.NHibernate
+{
+	[Serializable]
+	public abstract class GenericWellKnownInstanceType<T, TId> : IUserType where T : class
+	{
+		//private static readonly SqlType[] ReturnSqlTypes = { SqlTypeFactory.Int32 };
+		private Func<T, TId, bool> findPredicate;
+		private Func<T, TId> idGetter;
+		private IEnumerable<T> repository;
+
+		/// <summary>
+		/// Base constructor
+		/// </summary>
+		/// <param name="repository">The collection that represent a in-memory repository.</param>
+		/// <param name="findPredicate">The predicate an instance by the persisted value.</param>
+		/// <param name="idGetter">The getter of the persisted value.</param>
+		protected GenericWellKnownInstanceType(IEnumerable<T> repository, Func<T, TId, bool> findPredicate, Func<T, TId> idGetter)
+		{
+			this.repository = repository;
+			this.findPredicate = findPredicate;
+			this.idGetter = idGetter;
+		}
+
+		//public SqlType[] SqlTypes
+		//{
+		//    get { return ReturnSqlTypes; }
+		//}
+
+		public Type ReturnedType
+		{
+			get { return typeof(T); }
+		}
+
+		public bool IsMutable
+		{
+			get { return false; }
+		}
+
+		public new bool Equals(object x, object y)
+		{
+			if (ReferenceEquals(x, y))
+			{
+				return true;
+			}
+			if (ReferenceEquals(null, x) || ReferenceEquals(null, y))
+			{
+				return false;
+			}
+
+			return x.Equals(y);
+		}
+
+		public int GetHashCode(object x)
+		{
+			return (x == null) ? 0 : x.GetHashCode();
+		}
+
+		public object NullSafeGet(IDataReader rs, string[] names, object owner)
+		{
+			int index0 = rs.GetOrdinal(names[0]);
+			if (rs.IsDBNull(index0))
+			{
+				return null;
+			}
+
+			var value = (TId)rs.GetValue(index0);
+			return repository.FirstOrDefault(x => findPredicate(x, value));
+		}
+
+		public void NullSafeSet(IDbCommand cmd, object value, int index)
+		{
+			if (value == null)
+			{
+				((IDbDataParameter)cmd.Parameters[index]).Value = DBNull.Value;
+			}
+			else
+			{
+				((IDbDataParameter)cmd.Parameters[index]).Value = idGetter((T)value);
+			}
+		}
+
+		public object DeepCopy(object value)
+		{
+			return value;
+		}
+
+		public object Replace(object original, object target, object owner)
+		{
+			return original;
+		}
+
+		public object Assemble(object cached, object owner)
+		{
+			return cached;
+		}
+
+		public object Disassemble(object value)
+		{
+			return value;
+		}
+
+		/// <summary>
+		/// The SQL types for the columns mapped by this type. 
+		/// </summary>
+		public abstract SqlType[] SqlTypes { get; }
+	}
+}
\ No newline at end of file
--- a/Agendas/trunk/src/Agendas.NHibernate/NhHelper.cs	Thu Jul 28 10:16:09 2011 -0300
+++ b/Agendas/trunk/src/Agendas.NHibernate/NhHelper.cs	Fri Jul 29 16:30:53 2011 -0300
@@ -1,9 +1,14 @@
-using AltNetHispano.Agendas.Domain;
+using System;
+using System.Collections.Generic;
+using System.Data;
+using AltNetHispano.Agendas.Domain;
 using ConfOrm;
 using ConfOrm.NH;
 using NHibernate;
 using NHibernate.Cfg;
 using NHibernate.Tool.hbm2ddl;
+using NHibernate.Type;
+using NHibernate.UserTypes;
 
 namespace Agendas.NHibernate
 {
@@ -19,6 +24,9 @@
 				var orm = new ObjectRelationalMapper();
 				orm.TablePerClass<Persona>();
 				orm.TablePerClass<Evento>();
+
+				orm.Complex<Evento>(e => e.Estado);
+
 				orm.TablePerClass<Track>();
 				orm.TablePerClass<TrackLog>();
 				orm.TablePerClass<Cuenta>();
@@ -26,11 +34,13 @@
 
 				orm.Cascade<Evento, Persona>(Cascade.None);
 				orm.Cascade<Persona, Evento>(Cascade.None);
-				
+
 				orm.Cascade<Persona, Cuenta>(Cascade.All | Cascade.DeleteOrphans);
 
 				var mapper = new Mapper(orm);
 
+				mapper.AddPropertyPattern(p => p.DeclaringType == typeof(Evento) && p.Name == "Estado", a => a.Type<EventoStateType>());
+
 				var mapping = mapper.CompileMappingFor(typeof(Evento).Assembly.GetTypes());
 				
 				_cfg = new Configuration();
--- a/Agendas/trunk/src/Agendas.Repositories.Memory/EventoRepository.cs	Thu Jul 28 10:16:09 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Repositories.Memory/EventoRepository.cs	Fri Jul 29 16:30:53 2011 -0300
@@ -15,7 +15,7 @@
 
 		public IList<Evento> GetByState(EventoState state)
 		{
-			return Objects.Values.Where(e => e.Estado == state.GetDescripcion()).ToList();
+			return Objects.Values.Where(e => e.Estado == state).ToList();
 		}
 
 		public IList<Evento> GetActivos()
@@ -23,12 +23,12 @@
 			return
 				Objects.Values.Where(
 					e =>
-					e.Estado != EventoPublicadoState.GetInstance().GetDescripcion()).ToList();
+					e.Estado != EventoPublicadoState.GetInstance()).ToList();
 		}
 
 		public Evento GetPropuestaByTitulo(string titulo)
 		{
-			return Objects.Values.SingleOrDefault(e => e.Estado == EventoPropuestoState.GetInstance().GetDescripcion() && e.Titulo == titulo);
+			return Objects.Values.SingleOrDefault(e => e.Estado == EventoPropuestoState.GetInstance() && e.Titulo == titulo);
 		}
 
 		public static void Clear()
--- a/Agendas/trunk/src/Agendas.Repositories.NHibernate/EventoRepository.cs	Thu Jul 28 10:16:09 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Repositories.NHibernate/EventoRepository.cs	Fri Jul 29 16:30:53 2011 -0300
@@ -27,12 +27,12 @@
 			return
 				Session.QueryOver<Evento>().Where(
 					e =>
-					e.Estado != EventoPublicadoState.GetInstance().GetDescripcion()).List();
+					e.Estado != EventoPublicadoState.GetInstance()).List();
 		}
 
 		public Evento GetPropuestaByTitulo(string titulo)
 		{
-			return Session.QueryOver<Evento>().Where(e => e.Estado == EventoPropuestoState.GetInstance().GetDescripcion() && e.Titulo==titulo).SingleOrDefault();
+			return Session.QueryOver<Evento>().Where(e => e.Estado == EventoPropuestoState.GetInstance() && e.Titulo==titulo).SingleOrDefault();
 		}
 
 		public void Update(Evento evento)
@@ -42,7 +42,7 @@
 
 		public IList<Evento> GetByState(EventoState state)
 		{
-			return Session.QueryOver<Evento>().Where(e => e.Estado == state.GetDescripcion()).List();
+			return Session.QueryOver<Evento>().Where(e => e.Estado == state).List();
 		}
 	}
 }
--- a/Agendas/trunk/src/Agendas.Tests/AgendarTests.cs	Thu Jul 28 10:16:09 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Tests/AgendarTests.cs	Fri Jul 29 16:30:53 2011 -0300
@@ -216,7 +216,7 @@
 			var evento =
 				DefaultEventoRepository.GetByState(EventoPropuestoState.GetInstance()).Single(e => e.Titulo == "Html 5");
 
-			Assert.IsInstanceOf(typeof(EventoPropuestoState), evento.GetEstado());
+			Assert.IsInstanceOf(typeof(EventoPropuestoState), evento.Estado);
 			Assert.That(evento.GetTrackNews().Count(t => t.Accion == Accion.Proponer) == 1);
 		}
 
@@ -230,7 +230,7 @@
 
 			var evento = DefaultEventoRepository.GetActivos().Single(e => e.Titulo == "Html 5");
 
-			Assert.IsInstanceOf(typeof(EventoAgendadoState), evento.GetEstado());
+			Assert.IsInstanceOf(typeof(EventoAgendadoState), evento.Estado);
 			Assert.That(evento.GetTrackNews().Count(t => t.Accion == Accion.Agendar) == 1);
 		}
 
@@ -246,9 +246,9 @@
 
             agenda.Cancelar(evento.Id);
 
-            Assert.IsInstanceOf(typeof(EventoCanceladoState), evento.GetEstado());
+            Assert.IsInstanceOf(typeof(EventoCanceladoState), evento.Estado);
             Assert.That(evento.GetTrackNews().Count(t => t.Accion == Accion.Cancelar) == 1);
-            Assert.AreEqual(EventoCanceladoState.GetInstance().GetDescripcion(), evento.Estado);
+            Assert.AreEqual(EventoCanceladoState.GetInstance(), evento.Estado);
         }
 
         [Test]
@@ -264,9 +264,9 @@
             agenda.Cancelar(evento.Id);
             agenda.Descartar(evento.Id);
 
-            Assert.IsInstanceOf(typeof(EventoDescartadoState), evento.GetEstado());
+            Assert.IsInstanceOf(typeof(EventoDescartadoState), evento.Estado);
             Assert.That(evento.GetTrackNews().Count(t => t.Accion == Accion.Descartar) == 1);
-            Assert.AreEqual(EventoDescartadoState.GetInstance().GetDescripcion(), evento.Estado);
+            Assert.AreEqual(EventoDescartadoState.GetInstance(), evento.Estado);
         }
 	    
         [Test]
@@ -281,7 +281,7 @@
 
 			agenda.Confirmar(evento.Id);
 
-			Assert.IsInstanceOf(typeof(EventoConfirmadoState), evento.GetEstado());
+			Assert.IsInstanceOf(typeof(EventoConfirmadoState), evento.Estado);
 			Assert.That(evento.GetTrackNews().Count(t => t.Accion == Accion.Confirmar) == 1);
 		}
 
@@ -298,7 +298,7 @@
 			agenda.Confirmar(evento.Id);
 			agenda.Publicar(evento.Id, 0, string.Empty);
 
-			Assert.IsInstanceOf(typeof(EventoPublicadoState), evento.GetEstado());
+			Assert.IsInstanceOf(typeof(EventoPublicadoState), evento.Estado);
 			Assert.That(evento.GetTrackNews().Count(t => t.Accion == Accion.Publicar) == 1);
 		}
 
--- a/Agendas/trunk/src/Agendas.Tests/Agendas.Tests.csproj	Thu Jul 28 10:16:09 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Tests/Agendas.Tests.csproj	Fri Jul 29 16:30:53 2011 -0300
@@ -81,6 +81,7 @@
     <Compile Include="Cruds\PatrocinadorCrudNhTests.cs" />
     <Compile Include="Cruds\RequestEmulator.cs" />
     <Compile Include="DateTimeFormattingTests.cs" />
+    <Compile Include="EventoStateTests.cs" />
     <Compile Include="Eventos_y_patrocinadores_tests.cs" />
     <Compile Include="PersonaServiceTests.cs" />
     <Compile Include="PonentesTests.cs" />
--- a/Agendas/trunk/src/Agendas.Tests/Cruds/EventoCrud.cs	Thu Jul 28 10:16:09 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Tests/Cruds/EventoCrud.cs	Fri Jul 29 16:30:53 2011 -0300
@@ -123,5 +123,40 @@
 				Assert.IsNotNull(ponente);
 			}
 		}
+
+		public void Workflow()
+		{
+			Guid eventoId = Create();
+
+			using (_requestEmulator.Invoke())
+			{
+				Evento evento = _eventoRepository.Get(eventoId);
+				Assert.AreEqual(EventoPropuestoState.GetInstance(), evento.Estado);
+
+				evento.Agendar(evento.Ponente, evento.Fecha, null);
+			}
+
+			using (_requestEmulator.Invoke())
+			{
+				Evento evento = _eventoRepository.Get(eventoId);
+				Assert.AreEqual(EventoAgendadoState.GetInstance(), evento.Estado);
+
+				evento.Confirmar();
+			}
+
+			using (_requestEmulator.Invoke())
+			{
+				Evento evento = _eventoRepository.Get(eventoId);
+				Assert.AreEqual(EventoConfirmadoState.GetInstance(), evento.Estado);
+
+				evento.Publicar(1, null);
+			}
+
+			using (_requestEmulator.Invoke())
+			{
+				Evento evento = _eventoRepository.Get(eventoId);
+				Assert.AreEqual(EventoPublicadoState.GetInstance(), evento.Estado);
+			}
+		}
 	}
 }
\ No newline at end of file
--- a/Agendas/trunk/src/Agendas.Tests/Cruds/EventoCrudMemoryTests.cs	Thu Jul 28 10:16:09 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Tests/Cruds/EventoCrudMemoryTests.cs	Fri Jul 29 16:30:53 2011 -0300
@@ -60,5 +60,10 @@
 			_eventoCrud.Delete();
 		}
 
+		[Test]
+		public void Workflow()
+		{
+			_eventoCrud.Workflow();
+		}
 	}
 }
\ No newline at end of file
--- a/Agendas/trunk/src/Agendas.Tests/Cruds/EventoCrudNhTests.cs	Thu Jul 28 10:16:09 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Tests/Cruds/EventoCrudNhTests.cs	Fri Jul 29 16:30:53 2011 -0300
@@ -65,6 +65,12 @@
 		{
 			_eventoCrud.Delete();
 		}
+		
+		[Test]
+		public void Workflow()
+		{
+			_eventoCrud.Workflow();
+		}
 
 	}
 }
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Agendas/trunk/src/Agendas.Tests/EventoStateTests.cs	Fri Jul 29 16:30:53 2011 -0300
@@ -0,0 +1,23 @@
+using System.Linq;
+using Agendas.NHibernate;
+using AltNetHispano.Agendas.Domain;
+using NUnit.Framework;
+
+namespace AltNetHispano.Agendas.Tests
+{
+	[TestFixture]
+	public class EventoStateTests
+	{
+		[Test]
+		public void Check_all()
+		{
+			var definidos = EventoStateType.All;
+
+			var types = typeof (EventoState).Assembly.GetTypes();
+
+			int reflexion = types.Count(type => typeof(EventoState).IsAssignableFrom(type) && !type.IsAbstract);
+
+			Assert.AreEqual(definidos.Count(), reflexion);
+		}
+	}
+}
\ No newline at end of file
--- a/Agendas/trunk/src/Agendas.Web/Controllers/EventoController.cs	Thu Jul 28 10:16:09 2011 -0300
+++ b/Agendas/trunk/src/Agendas.Web/Controllers/EventoController.cs	Fri Jul 29 16:30:53 2011 -0300
@@ -22,15 +22,15 @@
 			            		                         		Id = e.Id.ToString(),
 			            		                         		Titulo = e.Titulo,
 			            		                         		Fecha = e.Fecha.HasValue ? e.Fecha.Value.ToShortDateString() : string.Empty,
-																Estado = e.Estado,
-			            		                         		PuedeAgendar = e.GetEstado().PuedePromover(Accion.Agendar),
-			            		                         		PuedeModificar = e.GetEstado().PuedePromover(Accion.Modificar),
-			            		                         		PuedeConfirmar = e.GetEstado().PuedePromover(Accion.Confirmar),
-			            		                         		PuedePublicar = e.GetEstado().PuedePromover(Accion.Publicar),
-                                                                PuedeCancelar = e.GetEstado().PuedePromover(Accion.Cancelar),
-                                                                PuedeDescartar = e.GetEstado().PuedePromover(Accion.Descartar),
-                                                                PuedeReAgendar = e.GetEstado().PuedePromover(Accion.ReAgendar),
-                                                                PuedeReProponer = e.GetEstado().PuedePromover(Accion.ReProponer)
+																Estado = e.Estado.Descripcion,
+			            		                         		PuedeAgendar = e.Estado.PuedePromover(Accion.Agendar),
+			            		                         		PuedeModificar = e.Estado.PuedePromover(Accion.Modificar),
+			            		                         		PuedeConfirmar = e.Estado.PuedePromover(Accion.Confirmar),
+			            		                         		PuedePublicar = e.Estado.PuedePromover(Accion.Publicar),
+                                                                PuedeCancelar = e.Estado.PuedePromover(Accion.Cancelar),
+                                                                PuedeDescartar = e.Estado.PuedePromover(Accion.Descartar),
+                                                                PuedeReAgendar = e.Estado.PuedePromover(Accion.ReAgendar),
+                                                                PuedeReProponer = e.Estado.PuedePromover(Accion.ReProponer)
 			            		                         	}
 			            	};
 			return View(model);