Правильно реализовать кеш в библиотеке классов для использования в приложении asp.net - PullRequest
8 голосов
/ 01 октября 2008

Я реализую кеш в библиотеке классов, которую я использую в приложении asp.net.

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

MyCacheObject.Instance.MyDataCollection

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

MyOtherCacheObject.Instance.MyOtherDataCollection(indexkey)

На этот раз был поднят вопрос о сборке мусора. Так как я храню огромное количество данных, не будет ли это пустой тратой, если они вдруг получат данные? Поскольку это всего лишь одноэлементный шаблон, ничто не гарантирует, что данные останутся в кэше.

Так что мой вопрос - какова лучшая практика для реализации кэша, чтобы справиться с этой ситуацией? Мне действительно не нравится огромное комплексное решение для этого, и я знаю, что в System.Web есть кеширование, но это кажется немного «выключенным», так как это всего лишь библиотека классов, или как вы думаете?

Ответы [ 2 ]

9 голосов
/ 01 октября 2008

На мой взгляд, лучшее решение будет иметь следующие характеристики:

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

  • Не связывает вашу библиотеку классов с System.Web, чтобы обеспечить согласованность слоев.

  • Но если библиотека классов работает внутри приложения ASP.NET, решение не должно требовать включения другой реализации кэширования (например, блока приложения кэширования Enterprise Library), которая требует дополнительной настройки и настройки.

Итак, я бы использовал стратегию IoC, чтобы позволить библиотеке классов использовать различные реализации кэширования в зависимости от среды, в которой она работает.

Предположим, вы определили свой абстрактный кеширующий контракт как:

public interface ICacheService 
{
    AddItem(...);
}

Вы можете предоставить реализацию на основе System.Web:

public AspNetBasedCacheService : ICacheService
{
    AddItem(...)
    {
        // Implementation that uses the HttpContext.Cache object
    }
 }

И затем эта реализация «публикуется» как синглтон. Обратите внимание, что отличие от вашего первоначального подхода в том, что синглтон - это просто ссылка на реализацию, основанную на службе кэширования ASP.NET, а не полный «объект кэша».

public class ChacheServiceProvider 
{
    public static IChacheService Instance {get; set;}

}

Вы должны были бы инициализировать реализацию chaching либо путем выполнения отложенной инициализации, либо при запуске приложения (в global.asax.cs)

И каждый компонент домена сможет использовать опубликованную службу кэширования, не зная, что она реализована на основе System.Web.

// inside your class library:
IChacheService chache = CacheServiceProvider.Instance;
cache.AddItem(...);

Я согласен, что это, вероятно, не самое простое решение, но я стремлюсь воспользоваться преимуществами реализации кэша ASP.NET без ущерба для развязки кода и гибкости.

Надеюсь, я правильно понял ваш вопрос.

1 голос
/ 01 октября 2008

Данные не будут собирать мусор, пока кэш все еще содержит ссылку на них.

Кроме того, никогда не используйте Singletons.

...