Re-Ejemplo de Lazy=Extra

Gracias al comentario de Fabio Maulo, sobre mi anterior post fue que decidí escribir escribir este post.

Evidentemente si alguien decide enumerar el diccionario tendremos un serio problema, ya que como antes mencioné, 3650 no es chiste. Aunque es un tema de mal uso de la api debería restringirlo de alguna manera. Entonces estuve estos últimos cinco minutos pensando como solucionarlo, y me vinieron dos ideas a la cabeza.

1er Idea: Propiedad indexada en la clase moneda

En vez de publicar una propiedad del tipo IDictionary<DateTime, Cotizacion>, publicar una propiedad indexada, por lo cual mi clase Moneda pasaría a ser así:

public class Moneda
{
    public virtual int Id { get; protected set; }
    public virtual string Nombre { get; set; }
    private readonly IDictionary<DateTime, Cotizacion> _cotizaciones;
    public virtual Cotizacion this[DateTime fecha]
    {
        get
        {
            Cotizacion cotizacionBuscada;
            if (_cotizaciones.TryGetValue(fecha, out cotizacionBuscada))
                return cotizacionBuscada;
            throw new InvalidOperationException("No existe cotización para la fecha buscada.");
        }
        set
        {
            _cotizaciones[fecha] = value;
        }
    }

    public Moneda()
    {
        _cotizaciones = new Dictionary<DateTime, Cotizacion>();    
    }
}

Y cómo va a hacer NHibernate para colocar las cotizaciones en ese field PRIVADO?
Simple solo ponemos este tag en el mapeo de la collection:

access="field"

Problema solucionado, nunca más se podrán enumerar (desde afuera) la colection.

2da Idea: NotEnumerableDictionary

Esta opción se me vino a la cabeza en el caso de que quisiera mantener la misma sintaxis que antes.

Les presento mi NotEnumerableDictionary (lo lamento no encontré un nombre mejor):

public class NotEnumerableDictionary<TKey, TValue>
{
    private readonly IDictionary<TKey, TValue> _dictionary;

    public NotEnumerableDictionary(IDictionary<TKey,TValue> dictionary)
    {
        _dictionary = dictionary;
    }

    public virtual TValue this[TKey key]
    {
        get
        {
            return _dictionary[key];
        }
        set
        {
            _dictionary[key] = value;
        }
    }
}

Ahora la clase Moneda quedaría así:

public class Moneda
{
    public virtual int Id { get; protected set; }
    public virtual string Nombre { get; set; }
    private readonly IDictionary<DateTime, Cotizacion> _cotizaciones;

    public virtual NotEnumerableDictionary<DateTime,Cotizacion> Cotizaciones
    {
        get
        {
            return new NotEnumerableDictionary<DateTime, Cotizacion>(_cotizaciones);
        }
    }

    public Moneda()
    {
        _cotizaciones = new Dictionary<DateTime, Cotizacion>();    
    }
}

Y el mapeo es igual que en el primer ejemplo.

En los dos ejemplos, de ninguna forma se puede utilizar linq para consultar esa collection. La consulta de Fabio debería ejecutarse así:

moneda.Cotizaciones[DateTime.Today.AddDays(-7)]

blog comments powered by Disqus
  • Categories

  • Archives