Где в моем классе я должен заполнить MemoryCache? - PullRequest
0 голосов
/ 29 ноября 2018

У меня есть класс, который возвращает кеш, в настоящее время используется:

var cache = new ProductCache().Get();

, тогда cache - это List<>, который можно перечислить.

вопрос действительно должен заполнитьэтот кеш при создании экземпляра ProductCache() в конструкторе или при его получении?

Опция 1:

 public class ProductCache
    {
        private readonly string key = "Product";
        private readonly object cacheLock = new object();
        ObjectCache cache = MemoryCache.Default;

        public ProductCache()
        {
        }

        public List<string> Get()
        {
            // Try to return.
            var data = cache.Get(key) as List<string>;

            if (data != null)
                return data;

            lock (cacheLock)
            {
                // Check again.
                data = cache.Get(key) as List<string>;

                if (data != null)
                    return data;

                // Populate, and return.
                data = PopulateFromElsewhere();
                cache.Set(key, data, DateTimeOffset.UtcNow.AddSeconds(20));
                return data;
            }
        }

        private List<string> PopulateFromElsewhere()
        {
            return new List<string> { "Ball", "Stick" };
        }
    }

Опция 2:

public class ProductCache
{
    private readonly string key = "Product";
    private readonly object cacheLock = new object();
    ObjectCache cache = MemoryCache.Default;

    public ProductCache()
    {
        var data = cache.Get(key);

        if (data != null)
            return;

        lock (cacheLock)
        {
            // Check again.
            data = cache.Get(key);

            if (data != null)
                return;

            // Populate, and return.
            PopulateFromElsewhere();
        }
    }

    public List<string> Get()
    {
        return cache.Get(key) as List<string>;
    }

    private void PopulateFromElsewhere()
    {
        var data = new List<string> { "Ball", "Stick" };
        cache.Set(key, data, DateTimeOffset.UtcNow.AddSeconds(20));
    }
}

- этовторой вариант потокобезопасен (достаточно)?я думаю во-первых ....

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

var storeCache = new StoreCache().Get();
var otherCache = new OtherCache().Get();

Я полагаю, что другой вариант - статический класс, но тогда потребуется дублирование механизмов блокировки, поскольку я не могу сделать это абстрактным ... это может быть довольно приятно,и используется как ...

var cache = GlobalCache.Stores();

1 Ответ

0 голосов
/ 29 ноября 2018

Если вы хотите повторно использовать логику кеша, но хотите иметь гибкость в своих дочерних классах, вы можете использовать шаблонный шаблон pattern:

public abstract class BaseCache
{
  private readonly object cacheLock = new object();
  protected ObjectCache cache = MemoryCache.Default;

  public List<string> Get()
  {
        // for example. It could be anywhere and return any type.
        ChildLogic();

        var data = cache.Get(key);

        if (data != null)
            return;

        lock (cacheLock)
        {
            // Check again.
            data = cache.Get(key);

            if (data != null)
                return;

            // Populate, and return.
            PopulateFromElsewhere();
        }
  }

  protected abstract void ChildLogic();
  protected abstract void PopulateFromElsewhere();
}

А затем в ваших дочерних классах вы должны реализовать ChildLogic() и PopulateFromElsewhere()любым способом, который вы хотите.

Конечно, вы не обязаны иметь метод ChildLogic() вообще.

...