Создать конструктор (?) Для извлечения объекта из кэша или воссоздать, если ноль
Я строю интранет, используя веб-формы C#. У меня есть объект списка с кучей пользователей, которых я кеширую. Я пытаюсь создать конструктор, который будет делать следующее, когда я ссылаюсь на MainADList:
- если он существует в кеше и не имеет значения null, используйте его
- еще генерировать список и кэшировать его
У меня есть код для кэширования и извлечения, но он не инкапсулирован так, как мне бы хотелось.
public Users MainADList = new Users();
private void GenerateADList()
{
MainADList = (Users) Cache["MainADList"];
if (MainADList == null || MainADList.Count == 0)
{
//generate the list....
Cache["MainADList"] = MainADList;
}
}
Спасибо!
3 ответа
Вы не можете создать конструктор, который делает это. Конструктор всегда создает новый объект.
Вместо этого создайте статический метод фабрики:
public static Users GetUsers()
{
// Consult the cache, and create a new instance if necessary.
}
Это может быть синглтон - но это определенно не обязательно. (Я бы не стал искусственно навязывать его синглтон-ность, если бы мне это не нужно. Я не большой поклонник синглтон-паттерна.)
В качестве альтернативы, вместо статического метода фабрики у вас может быть метод экземпляра в классе фабрики:
public class UsersFactory
{
// Construct it with a cache, or whatever's required
public Users GetUsers()
{
// Use the cache, or construct a new value.
}
}
Теперь это более тестируемо - потому что вы не полагаетесь ни на какое статическое (глобальное) состояние. Вместо этого вы можете создать новую фабрику из нового кэша в каждом тесте.
Во всех этих решениях вы должны учитывать, какое поведение потоков вам нужно. Если вы хотите убедиться, что вы создаете значение только один раз, вам нужно использовать Lazy<T>
, статический инициализатор гарантирует, или блокировка.
Вы можете следовать одной общей схеме:
public class ClassName {
public static Object CachedObject {
get {
Object o = (Object)Cache['CacheKey'];
if (o == null)
{
o = GetData();
Cache["CacheKey"] = o;
}
return o;
}
}
}
И относитесь к ClassName.CachedObject, как будто он всегда, вечно и магически заполнен.
То, что вы хотите, известно как синглтон.
В основном то, что вы должны делать с уже имеющимся кодом, выглядит примерно так:
public static GetList
{
get
{
//check if list exists and create it - so basically call your private constructor
//return cached list
}
}