Несколько раз в моем прошлом я хотел хранить данные в коде. Это могут быть данные, которые редко изменяются и используются в местах, где доступ к базе данных невозможен, практичен или нежелателен. Небольшим примером будет хранение списка стран. Для этого вы можете сделать что-то вроде:
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);
}
}
Я делал это раньше, потому что наборы данных были относительно небольшими, а объекты - довольно простыми. Сейчас я работаю с чем-то, что будет иметь более сложные объекты (по 5-10 свойств каждый, некоторые из них являются словарями) и всего около 200 объектов.
Сами данные меняются очень редко, а когда они меняются, это даже не так важно. Так что переходить на следующую версию совершенно нормально.
Я планирую использовать T4, ERB или другое шаблонное решение, чтобы превратить мой источник данных в нечто, что статически хранится в сборке.
Кажется, мои варианты
- Храните данные в XML. Скомпилируйте файл XML как ресурс сборки. Загружайте данные по мере необходимости, сохраняйте загруженные данные в словарь для повторного использования производительности.
- Создайте некоторый статический объект или объекты, которые инициализируются при запуске.
Я почти уверен, что понимаю последствия для варианта 1. По крайней мере, я догадываюсь, что у него не будет звездной производительности.
Что касается варианта 2, я не знаю, что делать. Я не знаю достаточно о внутренностях .NET Framework, чтобы знать, как на самом деле хранить эти данные в коде C # и как их инициализировать. Я изучил использование .NET рефлектора, чтобы увидеть, как это System.Globalization.CultureInfo.GetCulture(name)
работает, поскольку на самом деле этот рабочий процесс очень похож на то, что я хочу. К сожалению, этот след закончился extern
, так что никаких намеков там нет. Инициализация статического свойства со всеми данными, как в моем примере, путь? Или было бы лучше создать объекты по требованию и затем кэшировать их, как это?
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();
}
Преимущество их одновременного создания в статическом члене состоит в том, что вы можете использовать LINQ или что-либо еще, чтобы просматривать все объекты и запрашивать их, если хотите. Хотя я подозреваю, что это приводит к снижению производительности при запуске. Я надеюсь, что кто-то имеет опыт в этом и может поделиться своим мнением!