Algunas veces en mi pasado he querido almacenar datos en código. Estos serían datos que rara vez cambian y se usan en lugares donde el acceso a una base de datos no es posible, práctico o deseable. Un pequeño ejemplo sería almacenar una lista de países. Para eso podrías hacer algo como:
public class Country
{
public string Code { get; set; }
public string EnglishName {get;set;}
}
public static class CountryHelper
{
public static List<Country> Countries = new List<Country>
{
new Country {Code = "AU", EnglishName = "Australia"},
...
new Country {Code = "SE", EnglishName = "Sweden"},
...
};
public static Country GetByCode(string code)
{
return Countries.Single(c => c.Code == code);
}
}
He logrado hacer esto en el pasado porque los conjuntos de datos eran relativamente pequeños y los objetos bastante simples. Ahora estoy trabajando con algo que tendrá objetos más complejos (5 a 10 propiedades cada uno, algunas propiedades serán diccionarios) y alrededor de 200 objetos en total.
Los datos en sí cambian muy raramente y cuando cambian realmente no es tan importante. Así que pasarlo a la próxima versión de lanzamiento está perfectamente bien.
Estoy planeando usar T4 o ERB o alguna otra solución de plantillas para convertir mi fuente de datos en algo que esté almacenado estáticamente en el ensamblaje.
Parece que mis opciones son
- Almacena los datos en XML. Compile el archivo XML como un recurso de montaje. Cargue los datos según sea necesario, almacene los datos cargados en un Diccionario para un rendimiento de uso repetido.
- Genera algún tipo de objeto u objetos estáticos que se inicializan al inicio.
Estoy bastante seguro de que entiendo las implicaciones de rendimiento de la opción 1. Al menos, mi corazonada es que no tendría un rendimiento estelar.
En cuanto a la opción 2, no sé qué hacer. No sé lo suficiente sobre los aspectos internos de .NET framework para saber la mejor manera de almacenar realmente estos datos en código C # y las mejores maneras de inicializarlos. Hurgué con el reflector .NET para ver cómo funciona System.Globalization.CultureInfo.GetCulture(name)
, ya que este es realmente un flujo de trabajo muy similar al que quiero. Desafortunadamente, ese rastro terminó en extern
, por lo que no hay pistas allí. ¿Inicializar una propiedad estática con todos los datos, como en mi ejemplo, el camino a seguir? ¿O sería mejor crear los objetos a pedido y luego almacenarlos en caché, de esta manera?
private static readonly Dictionary<string, Country> Cache = new Dictionary<string,Country>();
public static Country GetByCode(string code)
{
if (!Cache.ContainsKey(code))
return Cache[code];
return (Cache[code] = CreateCountry(code));
}
internal static Country CreateCountry(string code)
{
if (code == "AU")
return new Country {Code = "AU", EnglishName = "Australia"};
...
if (code == "SE")
return new Country {Code = "SE", EnglishName = "Sweden"};
...
throw new CountryNotFoundException();
}
La ventaja de crearlos a la vez en un miembro estático es que puedes usar LINQ o cualquier otra cosa para mirar todos los objetos y consultarlos si lo deseas. Aunque sospecho que hacer esto tiene una penalización de rendimiento de inicio. Espero que alguien tenga experiencia con esto y pueda compartir sus opiniones.