Создать конструктор (?) Для извлечения объекта из кэша или воссоздать, если ноль

Я строю интранет, используя веб-формы C#. У меня есть объект списка с кучей пользователей, которых я кеширую. Я пытаюсь создать конструктор, который будет делать следующее, когда я ссылаюсь на MainADList:

  1. если он существует в кеше и не имеет значения null, используйте его
  2. еще генерировать список и кэшировать его

У меня есть код для кэширования и извлечения, но он не инкапсулирован так, как мне бы хотелось.

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
      }
}
Другие вопросы по тегам